How Do I Get the Position of a Character in a String using KM Actions?

This is extremely easy using AppleScript or JXA, but how do I do using only KM Actions?

I've searched extensively, and the closest solution I can find is, well, a kludge, using the "For Each" Action:

Surely there is a better way!?!?!

1 Like

Hey JM,

What about something like this?

Count Characters of Partial String.kmmacros (4.0 KB)

You can cut down on the variables used, but I've intentionally done this step-by-step to make what I'm doing as clear as possible.

NOTE: Keyboard Maestro's Filter Variable action performs the given filter ON the given variable.  (Users often expect filter someVariable to anotherVariable, but that's not now it works.)

As JM mentions this task is very straightforward in AppleScript:

tell application "Keyboard Maestro Engine" to set testSel to getvariable "testSel"
set subStringLength to offset of ";" in testSel

-Chris

Thanks for the suggestion, Chris.

But I really don't like either of our methods.
It looks like this just can't be done simply in KM Actions.

Of course, your script snippet is exactly what I had in mind:

tell application "Keyboard Maestro Engine" to set testSel to getvariable "testSel"
set subStringLength to offset of ";" in testSel

So, I gave up on non-script KM Actions, and wrote this script.
It takes the process through the next step of calculating the position of the END of the substring.

(*
==========================================================
  Get Position of End of Substring within Main String
==========================================================

RETURNS:
  • Position of End of StringToFind within MainString
  • 0 if StringToFind is NOT Found
  
VER:   1.0    LAST UPDATE:   2016-12-23

AUTHOR:    @JMichaelTX

Keyboard Maestro VARIABLES REQUIRED
  • SCPT__MainString -- string to be searched
  • SCPT__StringToFind -- sub-string to find within SCPT__MainString
  
REQUIRED:
  1.  Mac OS X Yosemite 10.10.5+
  2.  Keyboard Maestro 7.3+
==========================================================
*)

tell application "Keyboard Maestro Engine"
  set mainStr to getvariable "SCPT__MainString"
  set subStr to getvariable "SCPT__StringToFind"
end tell

if ((mainStr = "") or (subStr = "")) then
  error "ERROR:" & return & ¬
    "These KM Variables must be set and not empty:" & return & "SCPT__MainString" & return & "SCPT__StringToFind"
end if

### For Testing ###
--set mainStr to "1234;6789"
--set subStr to ";"

--- Get Start of StringToFind ---
set posSubStr to offset of subStr in mainStr

if (posSubStr > 0) then
  --- Add Length of StringToFind to Start Position ---
  set posSubStrEnd to posSubStr + (length of subStr) - 1
else
  set posSubStrEnd to 0
end if

return posSubStrEnd
1 Like

There are no real string “function” actions in Keyboard Maestro.

You can simply do:

  • For each TEST_PosOfChar in substrings “;” as position
    • Break from Loop

TEST_PosOfChar will retain its final value.

But there is no equivalent of “index(s)” that returns the position of the first matching string within another string. There probably should be, but generally when you want that you’ve probably already got reason to drop in to a script, or alternatively there is often a higher level way to accomplish the task.

1 Like