How to Solve This Problem With Capture Groups?

I have a macro that defines 10 capture groups to identify 10 strings between tags.

This works fine, as long as there are exactly 10 tag pairs.

However, when there are less tag pairs than capture groups, the macro seems to go into a loop.

This is the macro:

Untitled

How can I solve this?

The solution I can think of is to count the number of tag pairs and to use an IF statement: if there are 9 tag pairs, go to the handler for 9 capture groups.

Is this the way to go?

Tag Handler.kmmacros (4.6 KB)

EDIT: A tag pair counter could look like this:

Perhaps I can set the regex to a variable, and the variable’s length depending on the counter?

I’ll go that way!

BTW: Here:

I read:

there's no way to create a dynamic number of capture groups

Check out this:

And this:

2 Likes

Hey Hans,

Look at @JMichaelTX's macro that @martin has pointed you to.

You can't create dynamic capture groups in a single regular expression, but you CAN find the same regular expression multiple times in a given text.

JM's macro shows you how to do this with Keyboard Maestro.

You can either save each capture to a textual list:

CapA
CapB
CapC
...

Or you could use my macro that Martin points out to actually dynamically create a variable for each capture.

Then you can iterate through the results to process them.

Holler if you get stuck on this.

-Chris

1 Like

Hey Chris,

I tried to understand and use that code but indeed got stuck. I changed the lines to get a counter and wanted to use that for a clumsy approach to get a set of 10 capture groups:

If number of paired tags is 1, var captureGroup is:

.+(\</?x\d+/?\>.+\</?x\d+/?\>).+

Or maybe better:

.*?(\</?x\d+/?\>.*?\</?x\d+/?\>).*?

For 10 groups:

.+(\</?x\d+/?\>.+\</?x\d+/?\>).+(\</?x\d+/?\>.+\</?x\d+/?\>).+(\</?x\d+/?\>.+\</?x\d+/?\>).+(\</?x\d+/?\>.+\</?x\d+/?\>).+(\</?x\d+/?\>.+\</?x\d+/?\>).+(\</?x\d+/?\>.+\</?x\d+/?\>).+(\</?x\d+/?\>.+\</?x\d+/?\>).+(\</?x\d+/?\>.+\</?x\d+/?\>).+(\</?x\d+/?\>.+\</?x\d+/?\>).+(\</?x\d+/?\>.+\</?x\d+/?\>).+

But of course I’d be happier with an elegant and flexible solution (that even covers more than 10 groups).

Hans

Hey Hans,

Try this.

-Chris


Example of Matching and Capturing Substrings in a String v1.00.kmmacros (7.6 KB)

1 Like

Thanks, Chris.

It looks very simple, and it works. But don't ask me to explain what it does :).

I'll have work to do now: I'll have to replace the red action with actions to look up every corresponding target term for each source term (= Local_Line). Looks promising and flexible. To be cont.

:sunglasses:

The macro:

  1. Iterates through the source data looking for each match of the regular expression.

  2. When a match is found it adds it to the end of the matchFoundList variable with a linefeed to make sure it's on a new line.

  3. So you end up with a tidy text-list.

-Chris

1 Like

Thanks for the explanation.

Looks like I've done the crucial part now. Simple and thus only a few lines:

Very happy with this :). This is going te save me a lot of boring tag insertion work and lets me focus on the nice part: the actual translating.

1 Like