More Efficient Method of Extracting Regex Groups Inside for Loop?

Hey fellow nerds!

I frequently find myself needing to use regex matches within a For Loop, and usually start with something like the below image…

I always wonder to myself, "self, is there a more efficient way to do this?"

It seems redundant to put the regex statement twice, (first to match, then again to extract the groups to make us of their values later). If I need to edit the macro later, having the same regex statement twice sometimes makes me doubt whether they're actually identical or slightly different.

I suppose I could save the raw regex statement to a variable to reuse it in the For Loop action and the Search Variable action, but I found that that that approach can sometimes make the regex form fields (All: / 1: / 2: …) in the Search action disappear under certain circumstances which can confuse things.

I wonder if the regex match groups are already automatically accessible as a variable token somehow, similar to JSON dictionaries. For example, if my variable is named "myMatch", then something like %RegexMatch%myMatch[1]% would be useful. I have searched the documentation and forum, but couldn't find anything more efficient than what I'm already doing.

Thanks in advance for any tips!

Always a good question, but as I learned long ago: "Better is the enemy of good enough" :wink:

I agree, It IS redundant. Unfortunately, KM does NOT provide us with any other alternative.

I write a lot of Regex in AppleScript, and one of the Script Libraries I use provides a very useful, compact result. It returns multiple lists, one for each Match that was found.
Each Match Item contains 1-n items, one for the entire match, and then one item for each Capture Group.

I like your general idea, but I'm not following why you need the "[1]" notation.
Don't we want to just use the same RegEx pattern as above?

So, it would be very nice if @peternlewis could provide a, hopefully simple, enhancement: a KM token that refers to the Regex pattern entered in the above For Each:

What do you think Peter? Is this reasonable?

1 Like

If I was going to solve this, I would more likely (as I think @Joel_Rendall was suggesting) provide the captures as tokens, so %RegexMatch%1% used within the For Each actions would evaluate to the first capture group.

5 Likes

I hope this isn't too cheeky, but I'd like to now ask: are you going to solve it? :slight_smile:

1 Like

Wow, I'm always so humbled by the thoughtful responses in here from @JMichaelTX and of course @peternlewis (and others). What an incredible community, this makes KM even more fun and rewarding!

Yes Peter, that's exactly what I meant when I tried to refer to a token approach. (I think this answers what @JMichaelTX was asking that I clarify from my original post?).

I guess this token could be automatically available in situations like this for a variable used in a "for each" loop, and that's the most useful case I can think of. But maybe it could be used in other situations to save time too:

The "Search Using Regex" action could have an option to assign the regex match groups to its own variable for use later in the macro.

The action would work as is by default, but with there could be an option to capture the matches to itself instead of as variables:

The advantage here would be skipping the step of needing to choose variable names for each match, which could speed things up for those cases when you just want to use the matches for one or two actions. Also, if I need to adjust the regex pattern later and it changes the groups, then I don't have to worry about adjusting each form field if they get shifted around. (The disadvantage is that it would make a macro less readable since I'd have to remember or reinterpret what each regex match contains and is being used for).

So I admit the For Each use case is probably the most useful one.

Would love to see this since I use it every day, but I understand if you have bigger fish to fry :slight_smile:

Thanks for all your work and support!

@JMichaelTX I'm interested in learning more about this. Do you have any links to examples (or maybe macros buried in the forum somewhere) that you'd recommend I take a look at? Thanks in advance :slight_smile:

Maybe.

Since it is easily solved currently, with just a bit of redundancy, its not going to be a high priority.

1 Like

OK, that makes some sense.

But I don't understand how we would address ALL of the matches, and then for each match, ALL of the capture groups. Of course we would need to know how many matches, and how many CGs were returned. I can see this very clearly in ASObjC, but I can't visualize it in KM.

That's why I prefer my suggested method of simply referring to the same Regex pattern as used in the base For Each Action.

1 Like

If I can find some time tomorrow I'll post a good AppleScript regex example.

Hey Folks,

Here's one example of using AppleScript for the job.

User designated match-string, return-string, and return-separator-string.

The matches are returned as a text-list separated by the return-separator-string.

Result:

image

Find with Capture (AppleScript) v1.00.kmmacros (9.3 KB)

I thought this would be nearly a trifle in Perl, but I couldn't figure out how to pass the returned capture variables by variable. If anyone knows how please do educate me.

-Chris

1 Like

The issue with your suggestion is that the Search Variable action would not know the regex in advance, and thus have no way to know how many captures it contains, and no ability to let you set the variables in the editor.

The for each action iterates through the matches, and in the contained actions, you deal with the capture groups however you want. You would have to know how many capture groups they are, and use the appropriate numbers in the %RegexMatch%CAPTUREGROUPINDEX% token.

And if you change the regex, you also have to potentially change the tokens throughout the actions, so its not ideal either.

Basically, none of this is hugely better than just duplicating the regex.

2 Likes

@ccstone thanks very much for taking the time to create and share this example! Going to download and learn from the AppleScript.

1 Like