How do I get `string(REGEXP REPLACE ...)` to replace all instances

The documentation for string(REGEXP REPLACE ...) says

Match the <regular_expression> as many times as possible and substitute the <replacement_expression> for the match in the output. All <input> arguments are concatenated before matching.

I take “as many times as possible” to mean all instances that match the pattern will be replaced with the substitution pattern.

i.e. if the pattern matches multiple times, then each instance is updated.

However, I’m finding only the first instances of the pattern is being replaced.

Is there an additional flag that I’m missing that would cause the command to replace all matching patterns instead of just the first patter? Or perhaps the documenation is misleading me?

I’m using version 3.23.1 and my replacement logic is:

file(READ "${INC_FILE}" FILE_DATA)
set(FILE_DATA_ORIG "${FILE_DATA}")

#
# Update the #include paths
#
string(REGEX REPLACE
    "#include \"(.*h)\""
    "#include \"${PREFIX_DIR}/\\1\""
    NEW_DATA "${FILE_DATA}")

I’m attempting to update all #include paths in the specified file to add the PREFIX_DIR to it.

This works for the first #include found in the file, and fails for all the rest.

I think I’m zeroing in on the problem.

The pattern "#include \"(.*.h)\" will match newlines so for input of:

#include "foo.h"
#include "bar.h"

The expression that matches is

foo.h"
#include "bar.h

Which then gets substituted as:

<PREFIX_DIR>/foo.h"
#include "bar.h

Which is why only the first entry gets updated.

It also appears that CMake doesn’t follow the syntax where ? means non-greedy. So I’m trying to figure out how to work with the limited cmake regular expression syntax.

Got it.

For those that made it this far.

The command does replace all matching patterns. We just have to be careful with how much the pattern matches.

This pattern does what I want:

    "#include \"([^\"]+h)\""
                 ^^^^^^^
 match anything that isn't a quote up to an 'h' that
 is followed by a quote.