基本上,我有一个由多个以空格分隔的单词组成的字符串。然而,问题在于,单词之间可能会有多个空格而不仅仅是一个。这就是为什么[split]
不能达到我的要求的原因:
split "a b"
给我这个:
{a {} {} {} b}
使用以下代码替代:
{a b}
我在谷歌上搜索后发现Tcler's维基页面,其中一个用户提出了几乎相同的问题。
一种提议的解决方案如下所示:
split [regsub -all {\s+} "a b" " "]
似乎适用于简单字符串的情况。但是测试用的字符串
[string repeat " " 4]
(使用了 string repeat,因为 StackOverflow 会删除多个空格)将导致 regsub
返回 " ",而 split
再次将其拆分成 {{} {}}
而不是空列表。另一个提出的解决方案是这个,强制重新解释给定字符串作为列表:
lreplace "a list with many spaces" 0 -1
但是如果有一件事情我从TCL中学到的,那就是你永远不应该在字符串上使用列表函数(以l
开头)。实际上,这个函数会在包含特殊字符(即 { 和 })的字符串上产生错误:
lreplace "test \{a b\}"
返回的结果是test {a b}
而不是test \{a b\}
(我想要的是每个以空格分隔的单词拆分为结果列表中的单个元素)。
另一个解决方案是使用“过滤器”:
proc filter {cond list} {
set res {}
foreach element $list {if [$cond $element] {lappend res $element}}
set res
}
然后,您可以像这样使用它:
filter llength [split "a list with many spaces"]
同样的问题又出现了。这会在字符串上调用 llength
函数,如果字符串中包含特殊字符(例如 { 和 }),传入 "\{a b\}" 就会导致 TCL 抱怨 “列表中有无法匹配的开括号”。
我通过修改给定的 filter
函数,并在 if 语句中在 $cond 的前面添加 {*},这样我就可以使用 string length
而不是 llength
,它似乎对我尝试使用的每种可能的输入都有效。
这个解决方案现在安全可靠吗?它是否会在我没有测试的某些特殊输入上崩溃?或者,有没有更简单的方法做到这一点?
textutil::split
жҳҜеҸҰдёҖз§ҚйҖүжӢ©гҖӮ - kostix