首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将CMake分号分隔列表转换为换行符分隔的列表?

如何将CMake分号分隔列表转换为换行符分隔的列表?
EN

Stack Overflow用户
提问于 2017-01-13 11:33:52
回答 2查看 6.2K关注 0票数 5

例如:

代码语言:javascript
运行
复制
set (txt "Hello" "There" "World")
# TODO
message (txt) # Prints "Hello\nThere\nWorld" (i.e. each list item on a new line

我该放什么代替TODO?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-01-13 11:33:52

CMake的列表是分号分隔的。因此,"Hello" "There" "World"在内部表示为Hello;There;World。因此,一个简单的解决方案是用换行符替换分号:

代码语言:javascript
运行
复制
string (REPLACE ";" "\n" txt "${txt}")

但是,在本例中,这是可行的,但让我们尝试一个更复杂的示例:

代码语言:javascript
运行
复制
set (txt "" [[\;One]] "Two" [[Thre\;eee]] [[Four\\;rrr]])

[[ ]]是一个原始字符串,因此\被传递到CMake对列表的内部表示中,没有改变。内部表示是:;\;One;Two;Thre\;eee;Four\\;rrr。我们希望它能打印:

代码语言:javascript
运行
复制
<blank line>
;One
Two
Thre;eee
Four\\;rrr

我并不是百分之百地肯定Four\\;rrr的那一个,但我认为这是正确的。不管怎么说,通过我们天真的实现,我们实际上得到了以下内容:

代码语言:javascript
运行
复制
<blank line>
\
One
Two
Thre\
eee
Four\\
rrr

这是因为它不知道不转换实际的分号,而这些分号是转义的。解决方案是使用regex:

代码语言:javascript
运行
复制
string (REGEX REPLACE "[^\\\\];" "\\1\n" txt "${txt}")

也就是说,只有在前面有一个非;字符的情况下才替换\(并将该字符放入替换中)。它几乎可以工作,但是它不能处理第一个空元素,因为分号前面没有任何内容。最后的答案也是允许字符串的开始:

代码语言:javascript
运行
复制
string (REGEX REPLACE "(^|[^\\\\]);" "\\1\n" txt "${txt}")

哦,\\\\是因为一个级别的转义是通过处理字符串文本的CMake删除的,另一个级别是通过regex引擎删除的。你也可以这样做:

代码语言:javascript
运行
复制
string (REGEX REPLACE [[(^|[^\\]);]] "\\1\n" txt "${txt}")

但我认为这一点再清楚不过了。

也许有一个比这更简单的方法,但我找不到。不管怎样,女士们,先生们,这就是为什么你们不应该使用字符串作为你唯一的类型,或者做带内字符串的分隔。尽管如此,可能会更糟--至少他们没有像Bash那样使用空格作为分隔符!

票数 8
EN

Stack Overflow用户

发布于 2017-01-13 19:59:38

我只是想添加一些我看到的替代方案,仅仅是利用message()自己在末尾放了一个换行符这一事实:

  1. 只需使用for_each()对列表进行迭代: 设置(txt "Hello“"There”"World") foreach(列表中的行txt)消息(“${line}”) endforeach()
  2. 我想出的基于function()的替代方案看起来要复杂得多: 函数(message_cr行)消息(“${line}”) if (ARGN) message_cr(${ARGN}) endif() endfunction() set(txt "Hello“那里有"World") message_cr(${txt})

这些方法的更一般化的版本如下:

  1. 带字符串的for_each() 设置(txt "Hello“"There”"World") foreach(列表中的行txt)字符串(追加多行"${line}\n") endforeach()消息(“${ multiline }”)
  2. 带字符串的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)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41633738

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档