2013-12-12 34 views
1

當線條包含不平衡的大括號時,我在此正則表達式中收到錯誤消息。將不正確的大括號看作單詞的正則表達式

set line "a b { c{}" 
set lst [regexp -all -inline {^(\s*(\S*)\s*)*(\{(.*)\})?(\s*(\S*)\s*)*$} $line] 
set lst [lindex $lst 0] 
set firstelement [lindex $lst 0] 

如何避免這種情況下,把不平衡的大括號當作單詞處理?

回答

1

當你有一個來自任意源的字符串(比如用戶)時,根本不能保證它是一個格式良好的列表。現在regexp -inline返回匹配內容的列表,但該列表的元素是字符串(當然,除非您使用-indices選項),這意味着您無法安全地使用lindex來挑選它們。

的安全的方式來獲得的第一個「字」,假設你定義「字」是「非空格字符序列」(通常用戶定義),是要做到這一點:

set firstWord [lindex [regexp -all -inline {\S+} $item] 0] 

這有點難看,但它是完全安全的。 (事實上​​,對於第一字而已,對自己使用regexp -inline {\S+} $item,但不會讓你得到後話。)

使用split將字符串分解成的話也是可以的,但強烈假設單詞分隔符是單個(默認爲空白)字符,並執行一些您可能不希望的內容,如果您有多空白分隔符或前導空格和尾隨空格。坦率地說,將非空白分隔的字符串(例如,一個文件分成幾行,一個/etc/passwd記錄到字段中)或將字符串轉換爲字符列表(帶有空的第二個參數)會更有用。

1

regexp命令返回一個列表。然後你拿到列表的第一個元素。但是,在最後一行中,您將該元素視爲列表 - 但不能保證如此 - 因此實際的字符串內容很重要。相反,如果你要處理這個項目作爲一個列表中,您需要使用split,並將其轉換成文字:

% split "a b {" " " 
a b \{ 

你的情況:

set lst [lindex $lst 0] 
set firstelement [lindex [split $lst " "] 0] 

您可能還需要尋找到subst 。它看起來像你正在試圖讀取不良指定的TCL列表作爲輸入,並做一些解析,以獲得他們作爲一個正確的TCL列表。在這種情況下,subst -nocommands [lindex $lst 0]可能對您更有幫助。例如:

% lindex [subst -nocommands [lindex $lst 0]] 2 
c{} 

請注意,這是$ line的支撐部分的內容。

+0

「subst」怎麼幫助? –