例如:
set (txt "Hello" "There" "World")
# TODO
message (txt) # Prints "Hello\nThere\nWorld" (i.e. each list item on a new line
Run Code Online (Sandbox Code Playgroud)
我要用什么代替TODO?
CMake的列表以分号分隔。因此"Hello" "There" "World"在内部表示为Hello;There;World。因此,一个简单的解决方案是用换行符替换分号:
string (REPLACE ";" "\n" txt "${txt}")
Run Code Online (Sandbox Code Playgroud)
这在此示例中有效,但是让我们尝试一个更复杂的示例:
set (txt "" [[\;One]] "Two" [[Thre\;eee]] [[Four\\;rrr]])
Run Code Online (Sandbox Code Playgroud)
的[[ ]]是原始字符串,因此将\的原样传递到CMake的列表内部表示中。内部表示为:;\;One;Two;Thre\;eee;Four\\;rrr。我们希望它能打印:
<blank line>
;One
Two
Thre;eee
Four\\;rrr
Run Code Online (Sandbox Code Playgroud)
我实际上并不确定100%,Four\\;rrr但是我认为这是正确的。无论如何,通过天真的实现,我们实际上得到了以下信息:
<blank line>
\
One
Two
Thre\
eee
Four\\
rrr
Run Code Online (Sandbox Code Playgroud)
这是因为它不知道不转换逃脱的实际分号。解决方案是使用正则表达式:
string (REGEX REPLACE "[^\\\\];" "\\1\n" txt "${txt}")
Run Code Online (Sandbox Code Playgroud)
即,仅当替换字符;前面带有非\字符时才替换(并将该字符替换)。在差不多的工作,但因为分号不被任何东西之前它不处理的第一个空元素。最后的答案是也允许字符串的开头:
string (REGEX REPLACE "(^|[^\\\\]);" "\\1\n" txt "${txt}")
Run Code Online (Sandbox Code Playgroud)
哦,这\\\\是因为通过CMake处理字符串文字可删除一个转义级别,而通过正则表达式引擎则可删除另一个转义级别。您也可以这样做:
string (REGEX REPLACE [[(^|[^\\]);]] "\\1\n" txt "${txt}")
Run Code Online (Sandbox Code Playgroud)
但是我认为这不是很清楚。
也许有比这更简单的方法,但我找不到。无论如何,女士们,先生们,这就是为什么您永远不应该将字符串用作唯一类型或进行带内字符串定界的原因。不过,情况可能更糟-至少他们没有像Bash那样使用空格作为分隔符!
| 归档时间: |
|
| 查看次数: |
2328 次 |
| 最近记录: |