REGEX REPLACE and non-matching subpatterns
cmake's REGEX REPLACE
string function does not handle non-matching subpatterns as expected.
Suppose you want to insert a character (e.g., "c") to a string in front of another character (e.g., "d") if it exists, or append it at the end if it does not exist. Also, we don't care about repetitions.
I would expect this to work with string(REGEX REPLACE "([^dD]+)([dD])?(.*)" "\\1c\\2\\3" replace_str "${str}")
.
Unfortunately, this is not the care because empty subpattern matches are not simply ignored/replaced with an empty string but produce an error:
string sub-command REGEX, mode REPLACE: replace expression "\1c\2\3"
contains an out-of-range escape for regex "([^dD]+)([dD])?(.*)".
This is in contrast to other similar implementations such as sed
or perl
, e.g. echo "abf" | sed -Ee 's/([^dD]+)([dD])?(.*)/\1c\2\3/'
produces abfc
.
cmake's own MATCH
mode does not care about empty subpattern matches either, see attached example code.
My workaround is to use REGEX MATCH
and its match values (which also does not warn if they are used when empty(!).
string(REGEX MATCH "([^dD]+)([dD])?(.*)" dummy "${str}")
set(str "${CMAKE_MATCH_1}c${CMAKE_MATCH_2}${CMAKE_MATCH_3}")
This is somewhat related to #18690 but distinct enough from my perspective to warrant its own report.