2012-11-14 81 views
4

基本上,我有一個由多個空格分隔的單詞組成的字符串。然而,事情是可以有多個空格,而不是單獨分隔單詞。這就是爲什麼[split]沒有做什麼,我想:如何將字符串拆分爲TCL中的單詞列表,忽略多個空格?

split "a b" 

給了我這樣的:

{a {} {} {} b} 

,而不是這樣的:

{a b} 

搜索谷歌,我發現a page on the Tcler's wiki,其中一個用戶或多或少地提出了同樣的問題。

提出的一種方案是這樣的:

split [regsub -all {\s+} "a b" " "] 

這似乎爲簡單的字符串工作。但是如[string repeat " " 4](使用字符串重複,因爲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功能的工作,加入了{*}在$ COND前面的如果,所以我可以用它來與string length,而不是llength,這似乎對每一個可能的工作輸入我迄今試圖使用它。

此解決方案是否安全使用,因爲它現在是?它會嗆到我目前沒有測試過的一些特殊輸入嗎?或者,是否有可能以更簡單的方式做到這一點right

回答

14

最簡單的方法是使用regexp -all -inline選擇並返回所有單詞。例如:

# The RE matches any non-empty sequence of non-whitespace characters 
set theWords [regexp -all -inline {\S+} $theString] 

相反,如果你定義詞語是字母數字的序列,則使用它代替正則表達式術語:{\w+}

+1

使用['textutil :: split'](HTTP:// tcllib .sourceforge.net/doc/textutil_split.html)是Tcllib的另一種選擇。 – kostix

相關問題