RegEx that does NOT match desired pattern

Hi all,

I was looking into using the RegEx Actions to match multiple times - and that lead me to Peter's post:

So I did what Peter suggested. That is working fine. But my search also lead me to this post by @JMichaelTX

It seems like this would be more efficient or possible slightly quicker. I'm doing this multiple times for different variables and it adds up.

Anyhow, I'm just curious if the RegEx gurus could think up a pattern to NOT match the "UI element" NUMBER in a list?

Here's my current RegEx: regex101: build, test, and debug regex

It requires that I am looking for the "UI element #" ... but I'm only capturing this particular number into a list. So the pattern would be every BUT the # ... I don't want the "UI element" 'string' either ... that's only in the RegEx because I'm searching for the number linked to the UI element.

Thanks!

Well, I'm not at all clear what you're trying to avoid. But here's something to chew on:

element ([13579]+?)\s

will exclude elements with any even numbers (so no '16' but a '19').

element (\d+?)\s

will include any number following 'element'.

element ((?!17|19)[0-9]+?)\s

will skip any '17' or '19'.

All of these return just the number.

Thanks for the suggestions.

Basically my RegEx selects for the number that I want:

I want JUST the number value that comes after the 'UI element' string.

But I would rather find a RegEx that selects for everything EXCEPT for what I want. That way I can use the Search and Replace using RegEx Action and just replace everything else except for the UI element # value. And this means I don't need to use a For Each Loop and other actions.

All of those I suggested return just the number and nothing else. You retrieve it by referencing the capture group ($1 in your case, perhaps \2, depending on the language). The capture group is in green at regexe101.

I think it would be helpful to cite a specific example showing a small bit of text to search, what you specifically want to retrieve in that text and what you specifically want to avoid.

I believe I've shown you how to do all that in my examples.

Right, these RegEx patterns return just the number. But KM does not return ALL the matches unless you use a For Each Loop and iterate over all the RegEx matches using the Substrings In collection. This all works fine.

I'm looking to use the Search and Replace action. If I use my RegEx or your patterns I will be replacing the # value that I want. I want these # values in a list. So then the Search and Replace action would be to replace all the OTHER text that surrounds these number values. And so the RegEx would need to capture everything BUT these # values.

So in the text below I want to capture EVERYTHING that is NOT HIGHLIGHTED below. And essentially replace it with a space or \n or something - and then I could make the numbers that are left into a list.

So the RegEx pattern is essentially "everything that is NOT the number after the 'UI element' string".

,,,,,,,,, UI element 9 of group 1 of scroll area 2 of splitter group 2 of splitter group 1 of group 2 of group 2 of window Track_v01 - LPX_Template_v07 - Tracks of application process Logic Pro X, UI element 9 of group 1 of scroll area 2 of splitter group 2 of splitter group 1 of group 2 of group 2 of window Track_v01 - LPX_Template_v07 - Tracks of application process Logic Pro X, UI element 9 of group 1 of scroll area 2 of splitter group 2 of splitter group 1 of group 2 of group 2 of window Track_v01 - LPX_Template_v07 - Tracks of application process Logic Pro X,,,,,,, UI element 16 of group 1 of scroll area 2 of splitter group 2 of splitter group 1 of group 2 of group 2 of window Track_v01 - LPX_Template_v07 - Tracks of application process Logic Pro X, UI element 17 of group 1 of scroll area 2 of splitter group 2 of splitter group 1 of group 2 of group 2 of window Track_v01 - LPX_Template_v07 - Tracks of application process Logic Pro X, UI element 17 of group 1 of scroll area 2 of splitter group 2 of splitter group 1 of group 2 of group 2 of window Track_v01 - LPX_Template_v07 - Tracks of application process Logic Pro X,, UI element 19 of group 1 of scroll area 2 of splitter group 2 of splitter group 1 of group 2 of group 2 of window Track_v01 - LPX_Template_v07 - Tracks of application process Logic Pro X, UI element 19 of group 1 of scroll area 2 of splitter group 2 of splitter group 1 of group 2 of group 2 of window Track_v01 - LPX_Template_v07 - Tracks of application process Logic Pro X,,,,,,,,,,,,,,,,,,, UI element 38 of group 1 of scroll area 2 of splitter group 2 of splitter group 1 of group 2 of group 2 of window Track_v01 - LPX_Template_v07 - Tracks of application process Logic Pro X, UI element 38 of

So you want to delete any number after "UI element"? Here's how I'd do it in one line:

Delete Numbers.kmmacros (3.4 KB)

Put your data in a KM variable called $data and right before the regexp change my $data assignment to:

$data = $ENV{KMVAR_data};

No, I want to delete everything that is NOT the numbers after the “UI element” string.

Thanks for your help!

Change the code to:

while ($data =~ m/element (\d+?)\s/g) {
	$result .= "$1, ";
}
$result =~ s/, $//;

print $result;

That gives you a comma-delimited list of just the numbers. Edit to suit.

1 Like

Well, I was doubtful that this could be done, but this seems to work:
SEARCH FOR:
.*?(UI element (\d+)).+?(?=(UI element \d+)|$)

REPLACE WITH:
\2\n

See: regex101: build, test, and debug regex

Results In:

9
9
9
16
17
17
19
19
38
38

This is a complicated Positive Lookahead, which are already complicated.
I did NOT test this in KM, but it seems to work in Regex101.com

However, personally I would prefer the simple Regex used with a For Each.

Let us know if this works for you.

1 Like

Thanks to you both for helping out with this.

@JMichaelTX I agree that the For Each is much cleaner but it seems to quite a bit slower when you are doing 6 or so of these in a macro. That is, in addition to the 6 or so AppleScripts that are grabbing UI info which is already slow. Anyhow, I'm going to test this vs the For Each and see if I can shave a few seconds off the larger Macro, we'll see.

In any case, this seems to work in the few tests that I just did.

Thanks again for your help here. I tried all sorts of regex and couldn't crack it. I'm going to have to study yours and see if I can make full sense of it.

I wasn't able to get this to work. I was getting an error about a '(' ... I'd have to run it again. But no worries because I'm going to try the other solution for the time being and see which is quicker.

Thanks!

Sounds like you have a typo in the code. Just for the record, here's a more elaborate version (showing how to pass the data to the shell script and retrieve the results) that saves the numbers:

Save Numbers.kmmacros (5.1 KB)

1 Like

@JMichaelTX Using the Search and Replace vs the For Each shaved off at least a few seconds.

So thanks for that!

1 Like