CMake正则替换开头分号失效,所有分号被删除如何解决?
CMake正则替换前导分号失效问题解决方案
问题根因
分号是CMake的默认列表分隔符,你没有用双引号包裹${defs}时,CMake会自动将带分号的字符串拆分为多个独立的列表元素传入string命令,原始的分号在展开阶段就已经被丢弃,正则匹配实际是作用在拆分后的各个独立字符串上,最终多个替换结果直接拼接,就出现了所有分号消失的现象。
解决方案
方案1:修正正则替换写法(最直接适配需求)
给${defs}加上双引号,保留原始字符串中的所有分号,让正则可以正确匹配整个字符串的开头位置:
string(REGEX REPLACE "^;" "" stripped_defs "${defs}")
如果存在多个连续前导分号的场景,可以将正则调整为匹配一个及以上的开头分号:
string(REGEX REPLACE "^;+" "" stripped_defs "${defs}")
以上写法输出的结果就是你期望的-Dfoo;-Dbar。
方案2:用列表操作处理(更符合CMake原生逻辑)
编译定义本身就是CMake列表格式,前导分号对应列表开头的空元素,直接用列表操作处理稳定性更高:
- 如果你要删掉所有空元素(包括中间、尾部可能出现的空值):
list(FILTER defs EXCLUDE REGEX "^$") set(stripped_defs ${defs})
- 如果你仅需要删掉开头的前导空元素:
list(GET defs 0 first_elem) if(first_elem STREQUAL "") list(POP_FRONT defs) endif() set(stripped_defs ${defs})
注意事项
后续将stripped_defs传入target_compile_definitions等编译配置命令时,不要加双引号,直接传${stripped_defs}让其作为列表正常展开即可。
内容的提问来源于stack exchange,提问作者bremen_matt
相关产品推荐
相关产品推荐

