如何使用正则表达式替换来包围匹配组中的每个字符



我正在尝试定义一个正则表达式替换,它可以转换匹配组中的字符串并用引号将每个字符括起来。

例如,给定以下内容:

#define TEST_1  "Test String"
#define TEST_2  "Another Test String"

我想做一个正则表达式替换以获得:

char TEST_1[] = { 'T','e','s','t',' ','S','t','r','i','n','g' };
char TEST_2[] = { 'A','n','o','t','h','e','r',' ','T','e','s','t',' ','S','t','r','i','n','g' };

有没有办法在正则表达式中做到这一点,特别是 CMake 中的正则表达式?

我不确定是否可以按照您的要求通过一个 CMake 调用操作整行,但这里有一个需要几次调用的解决方案。

在这里,我们将初始字符串拆分在双引号上:

#define TEST_1  "Test String"

分为两部分:#define TEST_1Test String。接下来,我们对字符串的每个部分调用string(REGEX REPLACE ...)以适当地操作它。然后,我们在最后将这两个部分连接在一起:

# Define an initial string, for testing.
set(MYSTRING "#define TEST_1  "Test String"")
message("${MYSTRING}")
# Split the string into the unquoted and quoted portions.
string(REPLACE """ ";" MYSTRING_LIST ${MYSTRING})
list(GET MYSTRING_LIST 0 MYSTRING_BEGIN)
list(GET MYSTRING_LIST 1 MYSTRING_QUOTED)
# Perform regex replace to match the '#define TEST_N  ' portion, and
# replace it with 'char TEST_N[] = { '.
string(REGEX REPLACE "^#define TEST_([0-9]+)([ trn]*)" "char TEST_\1[] = { " STR_OUTPUT_BEGIN ${MYSTRING_BEGIN})
message("${STR_OUTPUT_BEGIN}")
# Perform regex replace on the quoted string portion, matching every
# character in the string, single-quoting and comma-separating each.
string(REGEX REPLACE "(.)" "'\1'," STR_OUTPUT_QUOTED ${MYSTRING_QUOTED})
# Remove the trailing comma appended in the previous regex-replace.
string(REGEX REPLACE ",$" "" STR_OUTPUT_QUOTED2 ${STR_OUTPUT_QUOTED})
message("${STR_OUTPUT_QUOTED2}")
# Concatenate them back together, appending the ' };' to the end.
string(CONCAT FINAL_STRING ${STR_OUTPUT_BEGIN} ${STR_OUTPUT_QUOTED2} " };")
message("${FINAL_STRING}")

所以你可以看到发生了什么,这打印:

#define TEST_1  "Test String"
char TEST_1[] = { 
'T','e','s','t',' ','S','t','r','i','n','g'
char TEST_1[] = { 'T','e','s','t',' ','S','t','r','i','n','g' };

如果您需要按照示例中所示处理多行,请将此逻辑放入 CMakefunction中并在循环中调用该函数应该相当容易。

这是有关如何执行此操作的示例

set( S "#define TEST_1  "Test String"" )             # Set string to beging with
string(REGEX REPLACE "#define[t ]*([a-zA-Z0-9_]+)" "char \1[] = { " S ${S} ) # "#define TEST_1" -> "char TEST_1[] = {"
string(REGEX MATCH ""([^"]+)"" RESULT ${S})         # get characters in string
set(RESULT ${CMAKE_MATCH_1})                           # RESULT = Test String
string(REGEX REPLACE "(.)" "'\1'," RESULT ${RESULT} ) # Replace each character with 'x',
string(LENGTH ${RESULT} iLength)                       # Calculate length
math(EXPR iLength "${iLength} - 1")                    # Decrease length with 1
string(SUBSTRING ${RESULT} 0 ${iLength} RESULT)        # Remove last comma
string(FIND ${S} "{" iPosition)                        # Find {
math(EXPR iPosition "${iPosition} + 1")                # Increase position with 1
string(SUBSTRING ${S} 0 "${iPosition}" S)              # Get substring
string(APPEND FINAL ${S} " " ${RESULT} " };"  )        # Build final string
message( STATUS "FINAL = ${FINAL}" )                   # Print final string

最新更新