例如:
set (txt "Hello" "There" "World")
# TODO
message (txt) # Prints "Hello\nThere\nWorld" (i.e. each list item on a new line
我该放什么代替TODO?
发布于 2017-01-13 11:33:52
CMake的列表是分号分隔的。因此,"Hello" "There" "World"
在内部表示为Hello;There;World
。因此,一个简单的解决方案是用换行符替换分号:
string (REPLACE ";" "\n" txt "${txt}")
但是,在本例中,这是可行的,但让我们尝试一个更复杂的示例:
set (txt "" [[\;One]] "Two" [[Thre\;eee]] [[Four\\;rrr]])
[[
]]
是一个原始字符串,因此\
被传递到CMake对列表的内部表示中,没有改变。内部表示是:;\;One;Two;Thre\;eee;Four\\;rrr
。我们希望它能打印:
<blank line>
;One
Two
Thre;eee
Four\\;rrr
我并不是百分之百地肯定Four\\;rrr
的那一个,但我认为这是正确的。不管怎么说,通过我们天真的实现,我们实际上得到了以下内容:
<blank line>
\
One
Two
Thre\
eee
Four\\
rrr
这是因为它不知道不转换实际的分号,而这些分号是转义的。解决方案是使用regex:
string (REGEX REPLACE "[^\\\\];" "\\1\n" txt "${txt}")
也就是说,只有在前面有一个非;
字符的情况下才替换\
(并将该字符放入替换中)。它几乎可以工作,但是它不能处理第一个空元素,因为分号前面没有任何内容。最后的答案也是允许字符串的开始:
string (REGEX REPLACE "(^|[^\\\\]);" "\\1\n" txt "${txt}")
哦,\\\\
是因为一个级别的转义是通过处理字符串文本的CMake删除的,另一个级别是通过regex引擎删除的。你也可以这样做:
string (REGEX REPLACE [[(^|[^\\]);]] "\\1\n" txt "${txt}")
但我认为这一点再清楚不过了。
也许有一个比这更简单的方法,但我找不到。不管怎样,女士们,先生们,这就是为什么你们不应该使用字符串作为你唯一的类型,或者做带内字符串的分隔。尽管如此,可能会更糟--至少他们没有像Bash那样使用空格作为分隔符!
发布于 2017-01-13 19:59:38
我只是想添加一些我看到的替代方案,仅仅是利用message()
自己在末尾放了一个换行符这一事实:
for_each()
对列表进行迭代:
设置(txt "Hello“"There”"World") foreach(列表中的行txt)消息(“${line}”) endforeach()function()
的替代方案看起来要复杂得多:
函数(message_cr行)消息(“${line}”) if (ARGN) message_cr(${ARGN}) endif() endfunction() set(txt "Hello“那里有"World") message_cr(${txt})这些方法的更一般化的版本如下:
for_each()
设置(txt "Hello“"There”"World") foreach(列表中的行txt)字符串(追加多行"${line}\n") endforeach()消息(“${ multiline }”)function()
函数(stringify_cr var行) if (ARGN) stringify_cr(${var} ${ARGN}) endif() set(${var}“${var}\n${var}}”PARENT_SCOPE) endfunction() set(txt "Hello“存在"World") stringify_cr(多行${txt})消息(${multiline})如果不喜欢末尾的额外换行符,请添加string(STRIP "${multiline}" multiline)
。
https://stackoverflow.com/questions/41633738
复制相似问题