String 如何在TCL中将字符串拆分为单词列表,忽略多个空格?
基本上,我有一个由多个空格分隔的单词组成的字符串。然而,问题是,单词之间可以有多个空格,而不是一个空格。这就是为什么String 如何在TCL中将字符串拆分为单词列表,忽略多个空格?,string,split,tcl,String,Split,Tcl,基本上,我有一个由多个空格分隔的单词组成的字符串。然而,问题是,单词之间可以有多个空格,而不是一个空格。这就是为什么[split]不执行我想要的操作: split "a b" 给我这个: {a {} {} {} b} 与此相反: {a b} 搜索谷歌,我发现,一个用户问了差不多相同的问题 一个建议的解决方案如下所示: split [regsub -all {\s+} "a b" " "] filter llength [split "a list with many
[split]
不执行我想要的操作:
split "a b"
给我这个:
{a {} {} {} b}
与此相反:
{a b}
搜索谷歌,我发现,一个用户问了差不多相同的问题
一个建议的解决方案如下所示:
split [regsub -all {\s+} "a b" " "]
filter llength [split "a list with many spaces"]
这似乎适用于简单字符串。但是像[string repeat”“4]
这样的测试字符串(使用string repeat是因为StackOverflow会占用多个空格)将导致regsub
返回“”,而split
将再次拆分为{}}
,而不是空列表
另一个建议的解决方案是,强制将给定字符串重新解释为列表:
lreplace "a list with many spaces" 0 -1
但是,如果我对TCL有一点了解的话,那就是永远不要在字符串上使用列表函数(从l
开始)。事实上,这个函数将阻塞包含特殊字符(即{和})的字符串:
返回test{abb}
,而不是test\{abb\}
(这就是我想要的,每个空格分隔的单词都被分割成结果列表的单个元素)
另一个解决方案是使用“过滤器”:
proc filter {cond list} {
set res {}
foreach element $list {if [$cond $element] {lappend res $element}}
set res
}
然后您可以这样使用它:
split [regsub -all {\s+} "a b" " "]
filter llength [split "a list with many spaces"]
同样的问题。这将对可能包含特殊字符(同样是,{and})的字符串调用llength
——传递它“{ab\}”将导致TCL抱怨“列表中的大括号不匹配”
我通过修改给定的filter
函数,在if中的$cond前面添加一个{*},使它能够与string length
一起使用,而不是llelength
,这似乎适用于我迄今为止尝试使用它的所有可能输入
这个解决方案现在使用安全吗?它会不会被一些我到目前为止还没有测试过的特殊输入阻塞?或者,是否可以用一种更简单的方法正确执行此操作?最简单的方法是使用
regexp-all-inline
选择并返回所有单词。例如:
# The RE matches any non-empty sequence of non-whitespace characters
set theWords [regexp -all -inline {\S+} $theString]
如果将单词定义为字母数字序列,则将其用作正则表达式术语:{\w+}
使用from Tcllib是另一个选项。