2014-06-20 43 views
2
set d(aa1) 1 
set d(aa2) 1                             
set d(aa3) 1 
set d(aa4) 1 
set d(aa5) 1 
set d(aa6) 1 
set d(aa7) 1 
set d(aa8) 1 
set d(aa9) 1 
set d(aa10) 1 
set d(aa11) 1 
set regexp "a*\[1-9\]" 
set res [array names d -glob $regexp] 
puts "res = $res" 

在這種情況下,結果是:瞭解tcl glob regexp?

res = aa11 aa6 aa2 aa7 aa3 aa8 aa4 aa9 aa5 aa1 

但是從a*\[1-9\]改變了正則表達式來a*\[1-10\]時,結果變成:

res = aa11 aa10 aa1 
+0

球體不是正則表達式;他們是[更受限制的語言](http://www.tcl.tk/man/tcl8.6/TclCmd/string.htm#M34),它更易於編寫,但功能卻不那麼強大。 –

回答

3

您的字符類的錯誤。

  • [1-10]並不意味着從1至10
  • 一個數字它意味着1-1,這是從11(即,僅僅是一個1)或0一個字符。這解釋了你的輸出。
  • 表示從1位至10,使用這樣的:(?:10?|[2-9])(如幾種方式之一做
  • 因此您正則表達式變得a*(?:10?|[2-9])
  • 請注意,如果您的引擎不允許非捕獲組,您需要刪除?:,用於:a*(?:10?|[2-9])
+0

很高興幫助。謝謝! :) – zx81

3

你需要確保你要匹配,因爲glob風格匹配和regexp風格匹配在很多方面都不同是什麼

。 10

the docs,圓頂封裝具有以下:

  • *任何字符序列匹配字符串,包括一個空字符串。
  • ?匹配字符串中的任何單個字符。
  • [chars]匹配由字符給出的集合中的任何字符。如果形式爲x-y的序列出現在字符中,則x和y之間的任何字符(包括x和y)都將匹配。當與-nocase一起使用時,範圍的端點將首先轉換爲小寫。而{[A-z]}匹配_時匹配區分大小寫(因爲_介於Za之間),與-nocase這被認爲是{[A-Za-z]}(可能是什麼意思首先)。
  • \x匹配單個字符x。這提供了避免模式中字符*?[]\的特殊解釋的方式。

由於您使用的glob風格匹配,您的當前表達式(a*\[1-9\])相匹配的a,其次是任何字符和1至9的任何一個(這意味着它也想abcjdne1匹配的東西)。

如果你想要匹配至少一個a隨後從1數到10,你需要這樣的事情,使用-regexp模式:

set regexp {a+(?:[1-9]|10)} 
set res [array names d -regexp $regexp] 

現在,這個正則表達式是我認爲更自然一個用於初學者((?:[1-9]|10)表示1到9或10,但您可以使用zx81建議的格式,(?:10?|[2-9])表示1,可選0表示10或2到9)。

+表示a必須至少出現一次才能匹配數組名稱。

如果你現在需要匹配的全名,你將需要使用錨:

^a+(?:[1-9]|10)$ 

注意:如果你想匹配至少一個a其次是數字和交替不能使用水珠匹配(管道使用|)和量詞(?+*),它們在正則表達式中的行爲方式不受glob匹配支持。最後,使用大括號來避免轉義你的模式(除非你有一個變量或者在你的模式中運行一個函數,否則就無法執行)。

+1

您可能需要錨定這些RE; Tcl不會默認將它們錨定... –

+0

@單調的權利。我以前沒有考慮過他們。 – Jerry