如何将字符串拆分为TCL中的单词列表,忽略多个空格?

Jer*_*rry 5 string split tcl

基本上,我有一个由多个空格分隔的单词组成的字符串.然而,事情是,可以有多个空格而不是只有一个分隔单词.这就是为什么[split]不做我想要的:

split "a    b"
Run Code Online (Sandbox Code Playgroud)

给我这个:

{a {} {} {} b}
Run Code Online (Sandbox Code Playgroud)

而不是这个:

{a b}
Run Code Online (Sandbox Code Playgroud)

在搜索Google时,我在Tcler的wiki上找到了一个页面,用户在那里提出了大致相同的问题.

一个建议的解决方案看起来像这样:

split [regsub -all {\s+} "a    b" " "]
Run Code Online (Sandbox Code Playgroud)

这似乎适用于简单的字符串.但是测试字符串如[string repeat " " 4](使用字符串重复,因为StackOverflow剥离多个空格)将导致regsub返回"",这split将再次分成{{} {}}而不是空列表.

另一个提议的解决方案是这个,强制重新解释给定字符串作为列表:

lreplace "a   list   with many   spaces" 0 -1
Run Code Online (Sandbox Code Playgroud)

但是,如果有一件事我已经了解了TCL,那就是你永远不应该l在字符串上使用列表函数(以...开头).事实上,这个会阻塞包含特殊字符的字符串(即{和}):

lreplace "test    \{a b\}"
Run Code Online (Sandbox Code Playgroud)

返回test {a b}而不是test \{a b\}(这将是我想要的,每个以空格分隔的单词分成结果列表的单个元素).

另一种解决方案是使用"过滤器":

proc filter {cond list} {
    set res {}
    foreach element $list {if [$cond $element] {lappend res $element}}
    set res
}
Run Code Online (Sandbox Code Playgroud)

然后你会像这样使用它:

filter llength [split "a   list   with many   spaces"]
Run Code Online (Sandbox Code Playgroud)

同样,同样的问题.这会调用llength一个字符串,它可能包含特殊字符(同样,{和}) - 传递它"\ {ab \}"会导致TCL抱怨"列表中无法匹配的开括号".

我设法通过修改给定的filter函数来使它工作,在if中的$ cond前面添加一个{*},所以我可以使用它string length代替llength,这似乎适用于我试图使用的每个可能的输入到目前为止.

这个解决方案现在可以安全使用吗?它到目前为止我没有测试一些特殊的输入吗?或者说,是有可能做到这一点的权利在一个简单的方法?

Don*_*ows 15

最简单的方法是使用regexp -all -inline选择并返回所有单词.例如:

# The RE matches any non-empty sequence of non-whitespace characters
set theWords [regexp -all -inline {\S+} $theString]
Run Code Online (Sandbox Code Playgroud)

相反,如果您将单词定义为字母数字序列,则将其用于正则表达式术语: {\w+}