Why is only the first match replaced?

Hi,

why is only the first match replaced using this macro when acting on multiple lines? The ''All Matches'' option has been chosen for this action.

Input:

*Test1
*Test2
*Test3
*Test4

Output:

* Test1
*Test2
*Test3
*Test4

Expected output:

* Test1
* Test2
* Test3
* Test4

Text ersetzen- Leerzeichen nach Aufzählungszeichen (*).kmmacros (2.4 KB)

Thanks for help!

If I know my Regex correctly you need to add the multiline (?m) flag to the beginning of the search string for it to match on each line. Otherwise the ^ will only match start of (whole) string.

Your search string would then look like: (?m)^\*([^ \t\r\n])

2 Likes

Thanks, this works. I don't get however, why other macros without this flag work for multi line replacement, e.g.

Text ersetzen- Punkt an Zeilenende (falls nicht vorhanden).kmmacros (2.4 KB)

As described in the reg ex reference the m flag controls the behavior of “^” and “$” in a pattern. By default these will only match at the start and end, respectively, of the input text. If this flag is set, “^” and “$” will also match at the start and end of each line within the input text.

So I don't know what your second example is supposed to do, but by default ^ matches only the start of the text, not the start of the line, and $ matches only the end of the text, not the end of the line.

1 Like

Out of interest, what does

image

...actually do? It looks like an overly complicated (== resource expensive) way of adding a period to the end of any string (or line, with the m option) that doesn't end with a period.

But lookaheads always confuse me. What am I missing?

To make this a bit more useful...

If you are developing/testing your regexs on regex101.com, remember that it defaults to "global, multiline":

image

...and you'll need to either change that or remember to add (?m) to the start of your pattern in KM.

Thanks @peternlewis for pointing me to the reference. @Nige_S: The action adds a period to the end of any line that doesn't end with a period :slight_smile: and the regex checks if the line ends with a period. There is likely a simpler way to implement this.

Yes. Keyboard Maestro defaults to global. But multiline is a different flag. As is single line. Neither of which are enabled by default in Keyboard Maestro.

1 Like

At my system I again have to add the multiline flag (?m), to the beginning of your search expression ^(?!.*\.$)(.*), for it to do what you are saying it is supposed to do.

But to make sure every line ends with at least one period, I think I'd set it up like this with Search And Replace using Regex:

Search and Replace.kmactions (561 B)
(KM v11.0.4)
Keyboard Maestro Export.

If one wants it to alway normalize the number of line ending periods to one, you could replace the question mark ? with an asterisk *, for it to match any number of consecutive line ending periods and replacing it with a single one.

1 Like