How to loop through lists in a Find and Replace?

I have two lists

1. Incorrect words
2. Correct words.

I have a document that has a find and replace dialogue. I would like to loop through the two lists to fill in the find and replace dialogue with the appropriate text.

E.g. When the Macro runs through the list the first time, it will put Colour in Find and Color in Replace, then on the second run-through, it will put nappy in Find and Diaper in Replace and so on.

I know that Keyboard Maestro has a Foreach command, so I thought I could use two of them, with one Foreach inside another.

However, it doesn't work as expected.
It will put Colour in Find and Color in Replace, which is correct.
But then on the second run-through, it will put Colour in Find and Diaper in Replace.

It's only looping through the second list and not the first one.

How can I fix this?

I have attached my macro (NB, in the macro, the incorrect words are called 'cuttoff words' because in the actual project, they incorrect words are words that are missing letters (e.g. they have been cuttoff midway)

hi, there's no macro attached

Whoops! here it is:

Find and Replace for incorrect words.kmmacros (8.0 KB)

If you're just trying to do a multiple search and replace, there are more efficient ways. See this thread for examples.

I saw that example earlier, but I was struggling without how to adapt it so it outputs the "wrong" text to Find the field of a Find and Replace dialogue and the "correct" text to the Replace field.

It doesn't use the Find or Replace field in a dialog box. It skips it entirely to do a multiple search and replace in a selection.

So you would do something like this for 'Colour':


Then make a selection in your text and run the macro. Presto

That wouldn't work for my use case, as I am doing the find and replace in a DTP application. If I take the text into another environment, I'd lose all my formatting and style sheet links etc when the text is pasted back in. I need to use the Find or Replace dialog box in the DTP app.

Ah, understood. If the app is InDesign, you can script the S&R operation in JavaScript (and there are plenty of examples of that online).

Otherwise, you might just try setting up a hot key or typed string to type the wrong word, a tab, and the right word for each combination to automatically fill out the fields.

I am using Affinity which doesn't support scripting.

That's what I am doing now. Actually, in this post, I've simplified my use case, it's actually more complex with more steps being done to the "correct" word after the find and replace.

Personally, I would pair the words up in one list, and then split them for each search&replace, something like:


1 Like

That worked! Thank you very much. :grinning:

1 Like

I have run into a little snag with this, as my word pairs contain a ":".

For example:
--american football 1:1-Holiday Activities: Football

In this, the first word in the pair is --american football 1
The second word in the pair is 1-Holiday Activities: Football

So when I run in the marco, KM gets confused. How can I adjust the (.*):(.*) to avoid this? I have tried replacing the ":" in the regular expression with another character (such as | and §) but it doesn't seem to work.

Any ideas? Thanks!

First, you always need to provide details for statements like "KM gets confused", which means nothing to us.

I'm guessing that the RegEx is being "greedy" (that's a Regex term) and is matching everything up to the 2nd colon.

This should work:

For details, see

1 Like

Whenever I use delimiters, I make sure that they're ones that will never occur in my text. The best way to ensure that is to use a multi-character delimiter (i.e., a string). Something like @~delimiter~@ will never be part of your text, so replacing : with @~delimiter~@ in the original regex will solve that.

1 Like

If it is concerning creating text that needs to be delimited, my first choice is always the TAB character. It is rarely used as a non-delimiter, and if I'm writing the text then I know whether or not it will be used that way.

The advantage of TABs is that they reduce clutter, help format the text for readability, and are very easy to use in most languages. Most often you can use "\t" to represent the TAB character in your code.

1 Like

It's a personal choice, of course, but tab doesn't work for me, because I frequently have tabs within text that I am trying to delimit. Also, I prefer gaudy strings like @~delimiter~@ because they're very easy to spot as delimiters.

1 Like