Trying to Figure Out RegEx Execution

I am having a heck of a time trying to wrap my brain around how regex operations work in KB. I have this block of text that I am searching through. I am looking for the Markdown footnote tags. The regex itself works properly. I've tested it online and in Patterns.

This is the block that I am running just to test (I know that the $(1) doesn't work that way).

So even though there are 5 capture groups in the text and I am using a For Each the action is only capturing one. This is what I get back from the log

2023-03-05 06:48:48 Execute macro “Footnote” from trigger Editor
2023-03-05 06:48:48 Log: Found: No footnotes found1

So it is only finding a single one (the 1 at the end) and it is also not setting the value of the footNotes as it indicates in the action that it would.

So I am not sure what I am doing wrong. Can anyone steer me in the correct direction?


You would need to tell us where you are headed.

What are you trying to produce ?

(You have shown us a sample of input, but left us guessing about the specifics of the output you are aiming for, so direction is not yet defined, for your readers)

XY problem - Wikipedia

I am not sure how the end results is an issue. I'm not asking how to produce an output.

I am asking why the regex isn't working to get all of the capture groups and why a variable isn't being set when the action indicates that it will be.

When people offer help, and think these things through, their time is taxed least (and their help proves most reliable) when they can do the thinking experimentally, seeing which routes work from A to B, and which ones don't.

If they don't know what B is, then A -> B is undefined, and the ratio of effort to reward is pushed higher.

Response rates fall, and the effort imposed on potential helpers rises.

A simple issue of effectiveness, as well as of civility.


Maybe you don't see it but I've actually found both your responses quite rude. This one especially.

Maybe if you are too taxed you shouldn't reply? In this case, you not replying would not have changed the status of this issue for me.

Thanks for your helpful critique of my question. I'll go someplacs a bit more civil and see if I can get a response.

Hey pixel geek, hope this helps.

Set Variable to Text.kmmacros (3.7 KB)



You are doing a regex search, but you have configured a case insensitive string search.

In Keyboard Maestro, “matching” means regex.

This would be much easier to troubleshoot if you posted an actual macro -- not just because I'm too lazy to type all that stuff out :wink: but also because I might miss invisible characters that you've inadvertently put in there and so on.

That said -- it looks like KM is doing exactly what you've told it to do. If you want to log the variable for every loop of the "For Each" action, try putting the logging action inside the "For Each" action.

1 Like

and you can also, of course, get a lot of flexibility with a script action:

MD FootNotes extracted.kmmacros (2.9 KB)

Expand disclosure triangle to view JS source
(() => {
    "use strict";

    const footNote = /^\[\^(\d+)\]:\s+(.*$)/u;

    return Application("Keyboard Maestro Engine")
    .flatMap(s => {
        const m = footNote.exec(s);

        return Boolean(m)
            ? [`${m[1]} -> ${m[2]}`]
            : [];

You will always get help faster, of course, if you share texts and macros rather than screenshots – they allow others to quickly:

  1. see what you are actually aiming for, and
  2. test.
### Footnotes

[^1]: Scrabble-like tiles. I don't want any over-enthusiastic junior IP lawyer at
Hasbro getting ready to send me a sternly worded Cease and Desist letter.

[^2]: I am sure that I have commented before on my unique idea of fun.

[^3]: As I have noted in other posts, I tend not to do a lot of error checking since
I am writing these for my own use. Typically you would want to check that the
user has provided you with usable and valid data.

[^4]: This would be a good spot to do some error checking to make sure that
what we were dealing with in the string was a letter and not something else.

[^5]: Another good spot for error checking.

This might help.

AFAIK you can't use capture groups directly from a "For Each... substring" regex -- each go round, your footnoteNumbers variable will be set to the entire matched substring, ie [^1], [^2]... But that just needs a bit of post-processing:

Footnotes Test.kmmacros (4.4 KB)