學習正則表達式的最好方法是從例子開始,理解例子之後再自己對例子進行修改,實驗。下麵給出了不少簡單的例子,並對它們作了詳細的說明。 假設你在一篇英文小說里查找hi,你可以使用正則表達式hi。 這幾乎是最簡單的正則表達式了,它可以精確匹配這樣的字元串:由兩個字元組成,前一個字元是h,後一個是i。通常,處 ...
學習正則表達式的最好方法是從例子開始,理解例子之後再自己對例子進行修改,實驗。下麵給出了不少簡單的例子,並對它們作了詳細的說明。
假設你在一篇英文小說里查找hi,你可以使用正則表達式hi。
這幾乎是最簡單的正則表達式了,它可以精確匹配這樣的字元串:由兩個字元組成,前一個字元是h,後一個是i。通常,處理正則表達式的工具會提供一個忽略大小寫的選項,如果選中了這個選項,它可以匹配hi,HI,Hi,hI這四種情況中的任意一種。
不幸的是,很多單詞里包含hi這兩個連續的字元,比如him,history,high等等。用hi來查找的話,這裡邊的hi也會被找出來。如果要精確地查找hi這個單詞的話,我們應該使用\bhi\b。
\b是正則表達式規定的一個特殊代碼(好吧,某些人叫它元字元,metacharacter),代表著單詞的開頭或結尾,也就是單詞的分界處。雖然通常英文的單詞是由空格,標點符號或者換行來分隔的,但是\b並不匹配這些單詞分隔字元中的任何一個,它只匹配一個位置。
如果需要更精確的說法,\b匹配這樣的位置:它的前一個字元和後一個字元不全是(一個是,一個不是或不存在)\w。
假如你要找的是hi後面不遠處跟著一個Lucy,你應該用\bhi\b.*\bLucy\b。
這裡,.是另一個元字元,匹配除了換行符以外的任意字元。*同樣是元字元,不過它代表的不是字元,也不是位置,而是數量——它指定*前邊的內容可以連續重覆使用任意次以使整個表達式得到匹配。因此,.*連在一起就意味著任意數量的不包含換行的字元。現在\bhi\b.*\bLucy\b的意思就很明顯了:先是一個單詞hi,然後是任意個任意字元(但不能是換行),最後是Lucy這個單詞。
換行符就是'\n',ASCII編碼為10(十六進位0x0A)的字元。
如果同時使用其它元字元,我們就能構造出功能更強大的正則表達式。比如下麵這個例子:
0\d\d-\d\d\d\d\d\d\d\d匹配這樣的字元串:以0開頭,然後是兩個數字,然後是一個連字型大小“-”,最後是8個數字(也就是中國的電話號碼。當然,這個例子只能匹配區號為3位的情形)。
這裡的\d是個新的元字元,匹配一位數字(0,或1,或2,或……)。-不是元字元,只匹配它本身——連字元(或者減號,或者中橫線,或者隨你怎麼稱呼它)。
為了避免那麼多煩人的重覆,我們也可以這樣寫這個表達式:0\d{2}-\d{8}。這裡\d後面的{2}({8})的意思是前面\d必須連續重覆匹配2次(8次)。
(如果需要更精確的說法,\b匹配這樣的位置:它的前一個字元和後一個字元不全是(一個是,一個不是或不存在)\w。)
(換行符就是'\n',ASCII編碼為10(十六進位0x0A)的字元。)
代碼 | 說明 |
---|---|
. | 匹配除換行符以外的任意字元 |
\w | 匹配字母或數字或下劃線或漢字 |
\s | 匹配任意的空白符 |
\d | 匹配數字 |
\b | 匹配單詞的開始或結束 |
^ | 匹配字元串的開始 |
$ | 匹配字元串的結束 |
代碼/語法 | 說明 |
---|---|
* | 重覆零次或更多次 |
+ | 重覆一次或更多次 |
? | 重覆零次或一次 |
{n} | 重覆n次 |
{n,} | 重覆n次或更多次 |
{n,m} | 重覆n到m次 |
代碼/語法 | 說明 |
---|---|
\W | 匹配任意不是字母,數字,下劃線,漢字的字元 |
\S | 匹配任意不是空白符的字元 |
\D | 匹配任意非數字的字元 |
\B | 匹配不是單詞開頭或結束的位置 |
[^x] | 匹配除了x以外的任意字元 |
[^aeiou] | 匹配除了aeiou這幾個字母以外的任意字元 |
分類 | 代碼/語法 | 說明 |
---|---|---|
捕獲 | (exp) | 匹配exp,並捕獲文本到自動命名的組裡 |
(?<name>exp) | 匹配exp,並捕獲文本到名稱為name的組裡,也可以寫成(?'name'exp) | |
(?:exp) | 匹配exp,不捕獲匹配的文本,也不給此分組分配組號 | |
零寬斷言 | (?=exp) | 匹配exp前面的位置 |
(?<=exp) | 匹配exp後面的位置 | |
(?!exp) | 匹配後面跟的不是exp的位置 | |
(?<!exp) | 匹配前面不是exp的位置 | |
註釋 | (?#comment) | 這種類型的分組不對正則表達式的處理產生任何影響,用於提供註釋讓人閱讀 |
代碼/語法 | 說明 |
---|---|
*? | 重覆任意次,但儘可能少重覆 |
+? | 重覆1次或更多次,但儘可能少重覆 |
?? | 重覆0次或1次,但儘可能少重覆 |
{n,m}? | 重覆n到m次,但儘可能少重覆 |
{n,}? | 重覆n次以上,但儘可能少重覆 |
名稱 | 說明 |
---|---|
IgnoreCase(忽略大小寫) | 匹配時不區分大小寫。 |
Multiline(多行模式) | 更改^和$的含義,使它們分別在任意一行的行首和行尾匹配,而不僅僅在整個字元串的開頭和結尾匹配。(在此模式下,$的精確含意是:匹配\n之前的位置以及字元串結束前的位置.) |
Singleline(單行模式) | 更改.的含義,使它與每一個字元匹配(包括換行符\n)。 |
IgnorePatternWhitespace(忽略空白) | 忽略表達式中的非轉義空白並啟用由#標記的註釋。 |
ExplicitCapture(顯式捕獲) | 僅捕獲已被顯式命名的組。 |
代碼/語法 | 說明 |
---|---|
\a | 報警字元(列印它的效果是電腦嘀一聲) |
\b | 通常是單詞分界位置,但如果在字元類里使用代表退格 |
\t | 製表符,Tab |
\r | 回車 |
\v | 豎向製表符 |
\f | 換頁符 |
\n | 換行符 |
\e | Escape |
\0nn | ASCII代碼中八進位代碼為nn的字元 |
\xnn | ASCII代碼中十六進位代碼為nn的字元 |
\unnnn | Unicode代碼中十六進位代碼為nnnn的字元 |
\cN | ASCII控制字元。比如\cC代表Ctrl+C |
\A | 字元串開頭(類似^,但不受處理多行選項的影響) |
\Z | 字元串結尾或行尾(不受處理多行選項的影響) |
\z | 字元串結尾(類似$,但不受處理多行選項的影響) |
\G | 當前搜索的開頭 |
\p{name} | Unicode中命名為name的字元類,例如\p{IsGreek} |
(?>exp) | 貪婪子表達式 |
(?<x>-<y>exp) | 平衡組 |
(?im-nsx:exp) | 在子表達式exp中改變處理選項 |
(?im-nsx) | 為表達式後面的部分改變處理選項 |
(?(exp)yes|no) | 把exp當作零寬正向先行斷言,如果在這個位置能匹配,使用yes作為此組的表達式;否則使用no |
(?(exp)yes) | 同上,只是使用空表達式作為no |
(?(name)yes|no) | 如果命名為name的組捕獲到了內容,使用yes作為表達式;否則使用no |
(?(name)yes) | 同上,只是使用空表達式作為no |