NAME
re_syntax - Tcl 正則表示式的語法。描述 DESCRIPTION
一個 正則表示式 (regular expression ) 描述了一類字串。它是匹配特定字串而不匹配其他的字串的一個模式。RE 的不同風格 DIFFERENT FLAVORS OF REs
正則表示式(“RE”)由 POSIX 定義,有兩種風格(flavor): 擴充套件 RE(``EREs'')和 基本RE(``BREs'')。ERE 粗略的相當於傳統的 egrep 的正則表示式,而 BRE 粗略的相當於傳統的 ed 的正則表示式。這個實現增加了第三種風格, 高階RE(``AREs''),它基本上是 ERE 再加上一些重要的擴充套件。 譯註:grep 預設支援 BRE,透過指定 -E 選項來支援 ERE,歷史上的 egrep 和 fgrep 已經合併入 grep 中。ed、sed 支援 BRE,lex、AWK 支援 ERE。 這個手冊頁主要描述 ARE。提供 BRE 主要是為了在一些老程式中反向(backward)相容;它們將最後討論。POSIX ERE 基本上是 ARE 的一個真子集。在 ERE 中不存在的 ARE 的特徵將被指示出來。正則表示式的語法 REGULAR EXPRESSION SYNTAX
實現 Tcl 正則表示式使用了 Henry Spencer 寫的包,基於 POSIX 1003.2 規定和一些(不是全部) Perl5 擴充套件 (感謝 Henry!)。下面的許多正則表示式描述是原封不動的從他的手冊頁複製過來的。 譯註:Perl5 的正則表示式也是從 Henry Spencer 所寫的包演變而來。 一個 ARE 是一個或多個由` |'分隔的分支(branch)(構成的),它匹配與任何一個分支匹配的一個字元序列。 一個分支是零或多個串聯起來的 約束(constraint)或定量原子(quantified atom)(構成的)。它與每個構件(約束或定量原子)所匹配的任何字元序列的一個串聯相匹配,組成這個字元序列的串聯的第一個字元序列與這個分支的第一個構件相匹配,第二個字元序列與第二個構件相匹配,以此類推。一個空分支匹配空串。 一個定量原子是可能跟隨一個單一的 定量符 (quantifier) 的原子。不加定量符,它匹配這個原子的一個匹配。定量符和它所定量的原子的匹配如下:- *
- 零個或多個這個原子的匹配的一個序列
- +
- 一個或多個這個原子的匹配的一個序列
- ?
- 零個或一個這個原子的匹配的一個序列
- {m}
- 嚴格的 m 個這個原子的匹配的一個序列
- {m,}
- m 或更多個這個原子的匹配的一個序列
- {m,n}
- 從 m 到 n (包括二者)個這個原子的匹配的一個序列; m 不能超過 n
- *? +? ?? {m}? {m,}? {m ,n}?
- 不貪婪的 (non-greedy) 定量符,它匹配與上面相同的可能性,但偏好最小字元數而不是最大字元數的匹配(參見MATCHING 匹配)。
- (re)
- (這裡的 re 是任何正則表示式) 匹配對 re 的一個匹配,為可能的報告而記錄(最長和最短的)匹配 譯註:使用圓括號來組合原子。例如,ab* 被識別為原子 a 和原子 b 的閉包 b* 的串聯 a(b)*,而不是原子 a 和原子 b 的串聯 ab 的閉包 (ab)*。捕獲的意思是把在圓括號中的子表示式所匹配的字元序列儲存下來,由後續的後引用去使用。
- (?:re)
- 同上,但不報告(設定為“非捕獲”的圓括號)
- ()
- 匹配一個空串,為可能的報告而記錄(匹配)
- (?:)
- 匹配一個空串,不報告
- [chars]
- 一個方括號表示式 ( bracket expression) ,匹配 chars 中的任何一個字元(詳情參見 BRACKET EXPRESSIONS 方括號表示式)
-
. - 匹配任何單一字元
- \k
- (這裡的 k 是一個非 alphanumeric (字母或數字)字元),匹配被接受為普通字元的這個字元,例如,\\ 匹配一個反斜槓字元
- \c
- (這裡的 c 是一個 alphanumeric 字元(可能跟隨著其他字元)),一個 轉義 (escape)(專屬 ARE),參見後面的ESCAPES 轉義)
- {
- 當跟隨著不是數字的一個字元的時候,匹配左花括號字元`{';在跟隨著一個數字的時候,它是一個束縛的開始(參見前面)
- x
- 這裡 x 是沒有其他意義的一個單一字元,匹配這個字元。
- ^
- 匹配一行的開始
- $
- 匹配一行的結束
- (?=re)
- 正前行(positive lookahead) (專屬 ARE),匹配任何與 re 相匹配的子串的開始端點
- (?!re)
- 負前行(negative lookahead) (專屬 ARE),匹配任何不與 re 相匹配的子串的開始端點
方括號表示式 BRACKET EXPRESSIONS
一個方括號表示式是一個在` []'中包圍的一個列表。它通常匹配列表中的任意一個單一字元(參見後面)。如果這個列表以“^”為開始,它匹配不屬於這個列表剩餘部分的任意一個單一字元(參見後面)。 如果在這個列表中的兩個字元被` -'分割,這是在歸併序列(collating sequence)中這兩個字元之間(包括二者)的字元的完整範圍的簡寫,例如, [0-9] 在 ASCII 中匹配任何十進位制數字。兩個範圍不能共享同一個端點,比如 a-c-e 是非法的。範圍是很依賴於整理序列的,可移植程式應該避免依靠它們。 譯註: 整理元素 -- 用來確定字元或寬字元字串的邏輯次序的最小實體。一個整理元素的組成要麼是一個單一字元,要麼是被整理為一個實體的兩個或更多字元。由當前地域(locale)中的 LC_COLLATE 類屬的值確定整理元素的當前設定。 譯註: 整理序列 -- 當前地域中的 LC_COLLATE 類屬的設定確定 整理元素的相對次序。這個字元次序定義所有整理元素的相對位置,在這個次序中每個元素都佔有一個唯一的位置。 要在這個列表中包括一個文字的 ] 或者 - ,最簡單的方法是把它包圍在 [. 和 .] 中使它成為一個整理元素(見後)。可替代的,使它成為第一個字元(跟隨在可能的‘ ^’的後面),或(專屬 ARE) 加以 ‘ \fR’先導。可選的,對於‘ -’,使它成為最後的字元,或一個範圍的第二端點。要使用一個文字 - 作為一個範圍的開始端點,可以使它成為一個整理元素或(專屬 ARE) 加以‘ \’先導。除了這些例外、一些使用 [ (參見下段)的組合、和轉義,在一個方括號表示式中的所有其他特殊字元失去其特殊意義。 在一個方括號表示式當中,在 [. 和 .] 當中包圍一個歸併元素(collating element)(一個字元、一個多字元序列被整理為如同一個單一字元,或給二者的一個整理序列名字)表示這個整理元素的一個字元序列。這個序列是這個方括號表示式列表中的一個單一元素。在有多字元整理元素的地域中,一個方括號表示式可以匹配多於一個字元。 所以(潛藏的),即使在方括號表示式中未出現多字元整理元素,以 ^ 為開始的一個方括號表示式仍可以匹配多字元整理元素! (注意:Tcl 目前沒有多字元整理元素。這些資訊只是用來解釋概念。) 例如,假定整理序列包含一個 ch 多字元整理元素,則 RE [[.ch.]]*c (後面跟隨著 c的零或多個 ch) 匹配`chchcc'的最先的5個字元。還有 [^c]b 匹配整個`chb'(因為 [^c] 匹配多字元 ch)。 在一個方括號表示式中,在 [= 和 =] 當中包含的一個整理元素是一個equivalence class 等價類,表示等價於這個整理元素的所有整理元素的字元序列,包括它自身。(如果沒有其他等價的整理元素,與在分界符` [.'和`.]'中包含一樣對待。) 例如,如果 o 和^ 是一個等價類的成員,則` [[=o=]]'、`[[=^=]]'、和`[o^]'都是同義詞。一個等價類不能是一個範圍的端點。 (注意:Tcl 目前只實現了 Unicode 地域。它不定義任何等價類。上面的例子只是用來解釋概念。) 在一個方括號表示式中,在 [: 和 :] 中包含的一個character class 字元類 的名字表示屬於這個類的所有字元的列表(不是所有整理元素!)。標準字元類有:alpha 一個字母 upper 一個大寫字母 lower 一個小寫字母 digit 一個十進位制數字 xdigit 一個十六進位制數字 alnum 一個 alphanumeric (字母或數字) print 一個 alphanumeric (同於 alnum) blank 一個空格或 tab 字元 space 在顯示的文字中產生白空格的一個字元 punct 一個標點字元 graph 有圖形表示的一個字元 cntrl 一個控制字元
轉義 ESCAPES
轉義(專屬 ARE),它以 \ 為開始後面跟隨著一個字母字元,存在一些變體: 字元錄入(entry)、類簡寫、約束轉義、和後引用。在 ARE 中,跟隨著一個 alphanumeric 字元但不約束一個有效轉義的 \ 是非法的。在 ERE 中,沒有轉義: 在方括號表示式外部,跟隨著一個 alphanumeric 字元的一個 \ 僅表示這個字元為一個普通字元,而在一個方括號表示式內部, \ 是一個普通字元。(後者是在 ERE 和 ARE 之間的一個實際上的不相容。) 字元錄入轉義 (Character-entry escapes) (專屬 ARE) 的存在簡便了在 RE 中指定一個非列印和其他非常規字元:- \a
- 警報(震鈴)字元,如同 C 語言
- \b
- 退格,如同 C 語言
- \B
- \ 的同義詞,在有多層反斜槓處理的一些應用中用來減少雙反斜槓
- \cX
- (這裡的 X 是任何字元) 字元的低端5位與 X 的低端5位相同,而其他位全是零
- \e
- 其整理序列名字是‘ESC’的字元,如果嘗試失敗,這個字元有八進位制值 033
- \f
- 換頁,如同 C 語言
- \n
- 換行,如同 C 語言
- \r
- 回車,如同 C 語言
- \t
- 水平 tab,如同 C 語言
- \uwxyz
- (這裡的 wxyz 是嚴格的四個十六進位制數字) 在本地位元組次序中的 Unicode 字元 U+wxyz
- \Ustuvwxyz
- (這裡的 stuvwxyz 是嚴格的八個十六進位制數字) 保留給假定的某種擴充套件到32位的 Unicode
- \v
- 垂直 tab,如同 C 語言
- \xhhh
- (這裡的 hhh 是十六進位制數字的任意序列) 其十六進位制值為 0xhhh 的字元(不管使用了多少十六進位制數字它都是一個單一字元)。
- \0
- 其值為 0 的字元
- \xy
- (這裡的 xy 是嚴格的兩個八進位制數字,並且不是一個 後引用(參見後面)) 其八進位制值為 0xy 的字元
- \xyz
- (這裡的 xyz 是嚴格的兩個八進位制數字,並且不是一個 後引用(參見後面)) 其八進位制值為 0xyz的字元
- \d
- [[:digit:]]
- \s
- [[:space:]]
- \w
- [[:alnum:]_] (注意有下劃線)
- \D
- [^[:digit:]]
- \S
- [^[:space:]]
- \W
- [^[:alnum:]_] (注意有下劃線)
- \A
- 只在字串開始處匹配(與 ` ^'的不同之處請參見下面的 MATCHING 章節)
- \m
- 只在一個字開始處匹配
- \M
- 在一個字的結束處匹配
- \y
- 只在一個字的開始處或結束處匹配
- \Y
- 只在一個字的不是開始處或結束處的某點上匹配
- \Z
- 只在一個字串的結束處匹配(與 ` $'的不同之處請參見下面的 MATCHING 章節)
- \m
- (這裡的 m 是一個非零數字)一個 back reference 後引用, 參見後面
- \mnn
- (這裡的 m 是一個非零數字,而 nn 是一些更多的數字,並且十進位制值 mnn 不大於目前為止閉合的捕獲圓括號的數目) 一個 後引用,參見下面
元語法 METASYNTAX
除了上面描述的主要的語法之外,還可獲得特殊形式和雜項的一些語法性的設施。 一般透過應用相關的方式指定使用的 RE 的風格。但是,可以用 指示符(director)來屏棄它們。如果某種風格的一個 RE 以‘ ***:’為開始,則 RE 的剩餘部分是一個 ARE。如果某種風格的一個 RE 以‘ ***=’為開始,則 RE 的剩餘部分被接受為一個文字串,並且其中的所有字元被認為是普通字元。 一個 ARE 可以以 embedded options 嵌入選項為開始: 一個序列 (?xyz) (這裡的 xyz 是一個或更多的字母字元) 指定影響 RE 剩餘部分的選項。它們提供和屏棄由應用指定的任何選項。可獲得的選項字母有:- b
- RE 的剩餘部分是一個 BRE
- c
- 大小寫敏感 (通常是預設的)
- e
- RE 的剩餘部分是一個 ERE
- i
- 大小寫不敏感 (參見下面的 MATCHING 匹配)
- m
- 歷史上的 n 的同義詞
- n
- 換行敏感匹配 (參見下面的 MATCHING 匹配)
- p
- 部分換行敏感匹配 (參見下面的 MATCHING 匹配)
- q
- RE 的剩餘部分是一個文字 (被引用起來的 ``quoted'')字串,都是普通字元
- s
- 非換行敏感匹配 (通常是預設的)
- t
- 緊湊語法 (通常是預設的;參見後面)
- w
- 反向部分換行敏感 (離奇的 ``weird'') 匹配 (參見下面的 MATCHING 匹配)
- x
- 展開語法 (參見後面)
保留有前導`
\'的白空格或 ` #'
保留在方括號表示式中的白空格或
` #'
在多字元符號如 ARE ` (?:'
或 ` \('
中間的白空格或註釋是非法的
展開語法中的白空格是
blank、tab
、和屬於空格字元類的任何字元。
最後,在 ARE
中,在方括號表示式外面,序列
` (?#ttt)' (這裡的 ttt
是不包含 ` )'
的任何文字)
是一個註釋,它將被完全忽略。同樣,不允許它在多字元符號如
`
(?:'中間的出現。這種註釋是歷史產物而不是很有用的設施,它的使用被淘汰了;應使用展開語法來替代。
如果應用(或一個啟始的
***=
指示符)指定使用者的輸入被作為一個文字串而不是一個
RE
來對待,則不能獲得這些元語法擴充套件。
匹配 MATCHING
譯註:下述引自 XBD RE 規定中的匹配定義,略有變更。 譯註:零個或多個字元的一個序列被稱為與 RE 匹配的條件是在這個序列中的字元對應於這個模式定義的一個字元序列。 譯註:對一個匹配的序列的查詢開始於一個字串的開始處,停止於找到第一個匹配字串的時候,這裡定義 第一個的意思為“字串中最早開始的”。如果模式允許匹配的字元有可變的數目,因此在這個點開始的序列多於一個,則匹配最長的那個序列。例如: RE bb* 匹配 abbbc 中的第2到第4個字元,而 RE (wee|week)(knights|night) 匹配 weeknights 的所有10個字元。 譯註:與整個匹配是最長的最左匹配相一致,從左到右的每個子模式,匹配最長的可能的字串。為此,一個空串被認為比根本沒有匹配長。例如,針對(against) abcdef 匹配 RE (.*).* ,子表示式 (1) 是 abcdef,而針對 bc 匹配 RE (a*)*,子表示式 (1) 是空串。 譯註:透過向每個子表示式遞迴的提供最左最長匹配來確定什麼(子)字串對應於子表示式是可能的,而附帶條件是整體匹配是最左的、最長的。例如,針對acdacaaa 匹配 (ac*)c*d[ac]*1 匹配出 acdacaaa (這裡 1=a); 而簡單的給 (ac*) 匹配最長的將生成 1=ac,但整體匹配將變小 (acdac)。概念上,實現必須檢查每種可能的匹配,並在生成的最左最長的總體匹配中,為最左子表示式挑出一個最長的匹配(子串)並以此類推。注意,這意味著子表示式的匹配是上下文相關的: 在一個很大的 RE 中的一個子表示式所匹配的字串可能與它作為一個獨立的 RE 時不同,還有,即使在類似的字元序列中,在同一個很大的 RE 中的同一個子表示式的兩個例項可能匹配不同的長度。例如,在 RE (a.*b)(a.*b) 中,兩個完全相同的子表示式將分別的匹配 accbaccccb 的四個和六個字元。 如果一個 RE 能匹配一個給定字串中的多於一個的子串,RE 匹配在這個字串中最先開始的子串。如果 RE能匹配的在這一點上開始的子串多於一個,它的選擇決定於它的 偏好(preference): 要麼是最長的子串,要麼是最短的子串。 多數原子和所有約束,都沒有偏好。一個有圓括號的 RE 與 RE 有相同的偏好(有可能沒有)。一個有 {m} 或 {m}? 定量符的定量原子與原子自身有相同的偏好(有可能沒有)。一個有其他平常的定量符的定量原子(包括在 {m,n} 中 m 等於 n) 偏好最長的匹配。一個有不貪婪定量符的定量原子(包括在 {m,n}? 中 m 等於 n 的情況) 偏好最短的匹配。一個分支與在它的裡面的第一個定量原子有相同的偏好。用 | 運算子連線起來的一個由兩個或多個分支組成的 RE 偏好最長的匹配。 取決於匹配整個 RE 的規則所強加的約束,基於可能子串的表現,子表示式可以匹配最長或最短的可能子串,在 RE 中開始較早的子表示式優先於開始較晚的。注意,外部的子表示式優先於其中的構件子表示式。 注意,可以分別的使用定量符 {1,1} 和 {1,1}? 在子表示式或整個 RE 上強制最長和最短偏好。 用字元數而不是整理元素數來測量匹配長度。一個空串被當作比根本沒有匹配長 ,例如 bb* 匹配 ` abbbc'中間的三個字元, (week|wee)(night|knights) 匹配 ` weeknights'的所有10個字元,在針對(against) abc 匹配 (.*).* 的時候圓括號中的子表示式匹配所有這三個字元,而在針對 bc 匹配 (a*)* 的時候整個 RE 和圓括號中子表示式都匹配一個空串。 如果指定了大小寫無關匹配,效果如同所有字母的大小寫區別都消失了。當存在大小寫區別的一個字元在方括號表示式外面作為一個普通字元出現的時候,它被有效的轉變成包含大小寫二者的一個方括號表示式, 所以 x 變成了`[xX]'。當它出現在一個方括號表示式中,把它對應的所有大小寫新增到方括號中,所以 [x] 變成 [xX]而 [^x] 變成 `[^xX]'。 如果指定了換行敏感匹配,則 . 和使用 ^ 的方括號表示式永不匹配換行字元(所以除非 RE 顯式安排,否則永不會跨越換行來進行匹配),並且 ^ 和 $ 除了分別匹配字串的開始和結束之外,還分別的匹配在換行之後和之前的空串。ARE [u548C] [u7E7C]續只匹配字串的開始和結束。 如果指定了部分換行敏感,這將致使 . 和方括號表示式成為換行敏感匹配,但不影響 ^ 和‘$’。 如果指定了反向部分換行敏感,這將致使 ^ 和 $ 成為換行敏感匹配,但不影響 . 和方括號。這不是很有用,提供它只是為了對稱。限制和相容性 LIMITS AND COMPATIBILITY
對於 RE 的長度沒有強加特定的限制。想要高度可移植的程式不應該依賴比 256 位元組長的 RE,因為遵從 POSIX 的實現可能拒絕接受這樣的 RE。 專屬 ARE 並且實際上與 POSIX ERE 不相容的特徵是在方括號表示式中的 \ 不失去它的特殊意義。所有其他 ARE 特徵使用的語法在 POSIX ERE 中是非法的,或著有未定義或未指定的效果;指示符的 *** 語法同樣不屬於 BRE 和 ERE 二者的 POSIX 語法。 許多 ARE 擴充套件取自 Perl,為了整理它們而進行了一些變更,還有一些 Perl 擴充套件未提供。要注意的不相容包括:‘ \b’、‘\B’,缺乏對尾隨的換行的特殊對待,為受換行敏感匹配影響的 RE 增加了方括號表示式補全,在先行約束中對圓括號和後引用的限制,和最長/最短匹配的匹配語義。 自從這個包的一個早期的 beta 測試版本做了變更以來,RE 的匹配的規則包含正常的和非貪婪的定量符二者。(新規則更加簡單和清晰,而不在猜測使用者的真實意圖上費很大力氣。) Henry Spencer 的原始的 1986 regexp 包,仍被廣泛的使用(例如,在 Tcl 8.1 之前的發行中),它實現了今天的 ERE 的一個早期版本。在 regexp 的近似 ERE (簡寫為 RRE)和 ARE 之間有四點不相容: In roughly increasing order of significance:在 ARE
中,跟隨著一個字母字元的
\
要麼是轉義要麼是一個錯誤,而在
RRE
中,它只是寫字母的另一種方式。這不應該是一個問題,因為在
RRE
中沒有理由寫出這樣的一個序列。
在 ARE
中跟隨著一個數字的
{
是一個束縛的開始,而在
RRE 中, {
總是一個普通字元。這樣的序列是少見的,並且經常導致一個錯誤,原因是隨後的字元看起來不象一個有效的束縛。
在 ARE 中,在` []'內 \
保持是一個特殊字元,所以在`
[]'內一個文字 \
必須寫成` \\'。在 RRE
中,在 []內 `\\'
也給出一個文字
\,但只有真正的偏執狂程式設計師才例行公事的雙寫反斜槓。
ARE 為 RE
報告最長的和最短的匹配,而不是按指定的查詢次序找到的第一個匹配。這可能影響寄希望於第一個匹配不被報告的一些
RRE。(廢棄了為快速匹配而最佳化查詢次序的
RRE 細緻工藝(ARE
並行的檢查所有可能的匹配,並且它們的效能在很大程度上不敏感於它們的複雜性),而為故意的找尋非最長或最短的一個匹配而開發的查詢次序需要重寫。)
基本正則表示式 BASIC REGULAR EXPRESSIONS
BRE 在一些方面與 ERE 有所區別。 ` |', `+', 和 ? 是普通字元並且沒有與之等價的功能。用於束縛的分界符是 \{ 和 ` \}', 而 { 和 } 本身是普通字元。用於巢狀子表示式的圓括號是 \( 和` \)', 而 ( 和 ) 自身是普通字元。除了在 RE 或一個圓括號中的子表示式的開始處之外, ^ 是一個普通字元,除了在 RE 或一個圓括號中的子表示式的結束處之外, $ 是一個普通字元,而在 RE 或一個圓括號中的子表示式的開始處之外出現的 * 是一個普通字元(在可能的前導 ` ^' 之後)。最後,可獲得單一數字的後引用, \< 和 \> 分別是 [[:<:]] 和 [[:>:]] 的同義詞;沒有其他可獲得的轉義。參見 SEE ALSO
RegExp(3), regexp(n), regsub(n), lsearch(n), switch(n), text(n)關鍵字 KEYWORDS
match, regular expression, string[中文版維護人]
寒蟬退士[中文版最新更新]
2001/10/26《中國 Linux 論壇 man 手冊頁翻譯計劃》:
http://cmpp.linuxforum.net跋
本頁面中文版由中文 man 手冊頁計劃提供。8.1 | Tcl |