正規表示式入門

2021-04-26 21:03:05 字數 4415 閱讀 6698

對於文字字元,有11個字元被保留作特殊用途。他們是:

[ ] / ^ $ . | ? * + ( )

這些特殊字元也被稱作元字元

不可顯示字元

可以使用特殊字串行來代表某些不可顯示字元:

<>代表tab(0x09)

<>代表回車符(0x0d)

<>代表換行符(0x0a)

字符集

字符集是由一對方括號「」括起來的字元集合。使用字符集,你可以告訴正規表示式引擎僅僅匹配多個字元中的乙個。如果你想匹配乙個「a」或乙個「e」,使用<<[ae]>>,你可以使用

<>匹配gray或grey

你可以使用連字元「-」定義乙個字元範圍作為字符集。

<<[0-9]>>匹配0到9之間的單個數字

<<[0-9a-fxa-fx]>>匹配乙個十六進製制數字或字母x。再次強調一下,字元和範圍定義的先後順序對結果沒有影響

查詢程式語言的識別符號,

<>。

(*表示重複0或多次)

查詢c風格的十六進製制數

<<0[xx][a-fa-f0-9]+>>。

(+表示重複一次或多次)

在左方括號「[」後面緊跟乙個尖括號「^」,將會對字符集取反

。結果是字符集將匹配任何不在方括號中的字元

因為一些字符集非常常用,所以有一些簡寫方式

<>代表<<[0-9]>>;

<>代表單詞字元。這個是隨正規表示式實現的不同而有些差異。絕大多數的正規表示式實現的單詞字符集都包含了<>。

<>代表「白字元」。這個也是和不同的實現有關的。在絕大多數的實現中,都包含了空格符和tab符,以及回車換行符<>

使用?*或+進行重複

?:告訴引擎匹配前導字元0次或一次。事實上是表示前導字元是可選的。

+:告訴引擎匹配前導字元1次或多次

*:告訴引擎匹配前導字元0次或多次

如果你用「?*+」操作符來重複乙個字符集,你將會重複整個字符集。而不僅是它匹配的那個字元。正規表示式

<<[0-9]+>>會匹配837以及222

你可以用

<>匹配1000~9999之間的數字(「/b」表示單詞邊界)。

<>匹配乙個在100~99999之間的數字

惰性擴充套件的乙個替代方案

我們還有乙個更好的替代方案。可以用乙個貪婪重複與乙個取反字符集:「<[^>]+>」。之所以說這是乙個更好的方案在於使用惰性重複時,引擎會在找到乙個成功匹配前對每乙個字元進行回溯。而使用取反字符集則不需要進行回溯

「.」匹配乙個單個的字元而不用關心被匹配的字元是什麼。唯一的例外是新行符。在本教程中談到的引擎,預設情況下都是不匹配新行符的。因此在預設情況下,「.」等於是字符集[^/n/r](window)或[^/n]( unix)的簡寫

「^」匹配一行字串第乙個字元前的位置。<<^a>>將會匹配字串「abc」中的a。<<^b>>將不會匹配「abc」中的任何字元。

類似的,$匹配字串中最後乙個字元的後面的位置。所以<>匹配「abc」中的c

單詞邊界

元字元<>也是一種對位置進行匹配的「錨」。這種匹配是0長度匹配

有4種位置被認為是「單詞邊界」: 1)

在字串的第乙個字元前的位置(如果字串的第乙個字元是乙個「單詞字元」)

2)在字串的最後乙個字元後的位置(如果字串的最後乙個字元是乙個「單詞字元」)

3)在乙個「單詞字元」和「非單詞字元」之間,其中「非單詞字元」緊跟在「單詞字元」之後 4)

在乙個「非單詞字元」和「單詞字元」之間,其中「單詞字元」緊跟在「非單詞字元」後面

「單詞字元」是可以用「/w」匹配的字元,「非單詞字元」是可以用「/w」匹配的字元。在大多數的正規表示式實現中,「單詞字元」通常包括

<<[a-za-z0-9_]>>

子表示式

由()包圍的才算乙個表示式!

子表示式(子模式,subpatterns)可以有以下作用:

1. 將多選一的分支區域性化。

例如,模式: cat(aract|erpillar|)匹配了 "cat","cataract" 或 "caterpillar" 之一,沒有圓括號的話將匹配 "cataract","erpillar" 或空字串。

2. 將子模式設定為捕獲子模式(例如上面這個例子)。當整個模式匹配時,目標字串中匹配了子模式的部分可以通過逆向引用進行呼叫。左圓括號從左到右計數(從 1 開始)以取得捕獲子模式的數。

注意,子模式是可以巢狀的,例如,如果將字串 "the red king" 來和模式 /the ((red|white) (king|queen))/進行匹配,捕獲的子串為 "red king","red" 以及 "king",並被計為 1,2 和 3 ,可以通過"/1","/2","/3"來分別引用它們,"/1"包含了"/2"和"/3",它們的序號是由左括號的順序決定的

非捕獲子模式(non-capturing subpatterns)

用一對括號同時完成上面提到的子模式的兩個功能有時會出現一些問題,例如,由於逆向引用的數目是有限的(通常最大不超過9),而且經常會遇到無需捕獲的子模式定義。這時,可以在開始的括號後加上問號和冒號來表示這個子模式無需捕獲,就向下面這樣:((?:red|white) (king|queen))。

如果將"the white queen"作為模式匹配的目標字串,則捕獲的字串有"white queen"和"queen",分別作為"/1"和"/2",white雖然符合子模式"(?:red|white)",但並不**獲

對於非捕獲子模式,舉個列子:

reg.subject := '生長階段:12%

再過1小時48分長高一些

距離收穫:1天21小時48分

';reg.regex := '距離收穫:(?:(/d+)天)?(?:(/d+)小時)?(?:(/d+)分)?(?:(/d+)秒)?';

while reg.matchagain do

begin

day := reg.subexpressions[1]; //得到1天中的1

hour := reg.subexpressions[2];//得到21小時中的21

min := reg.subexpressions[3]; //得到48分中的48

sec:= reg.subexpressions[4];

end;

倘若沒有上述表示式中的問號加冒號?:,

則會得到

day := reg.subexpressions[1]; //得到1天

hour := reg.subexpressions[2];//得到1天中的1

min := reg.subexpressions[3]; //得到48分

sec:= reg.subexpressions[4]; //得到48分中的48

即引擎認為出現了8個表示式而非四個!

//提取子表示式匹配到的內容

var

reg: tperlregex;

begin

reg := tperlregex.create(nil);

reg.subject := 'abc a1111 bb222 ccc33 dddd4';

reg.regex := '/b([a-d]+)([1-4]+)/b'; //這個表示式有兩個子表示式構成

whilereg.matchagaindo

begin

showmessage(reg.subexpressions[0]); //將分別顯示: a1111 bb222 ccc33 dddd4

showmessage(reg.subexpressions[1]); //將分別顯示: a bb ccc dddd

showmessage(reg.subexpressions[2]); //將分別顯示: 1111 222 33 4

再比如reg.regex := '([^<]+)

';正因為有了2對(),所以以下呼叫才能成功

text := text + reg.subexpressions[1] + #13 ;//表示第一對()內的值1608336

text := text + reg.subexpressions[2] + #13 ;//表示第二對()內的值

注:上述例子援引自jailu的開源專案

正規表示式 正則入門

先從乙個例子開始正規表示式。書寫乙個匹配手機號的正規表示式,為了方便討論,假定手機號是1開頭,第二位只能是3 5 8中的其中乙個,總共11位的數字,形如13 匹配手機號的正規表示式為 1 358 d 下面介紹此正規表示式中的各個符號的含義。表示字串的開頭,後面緊接著1,表示匹配的字串要以 1 開頭。...

正規表示式入門

老師說過 正規表示式就是用字串讀取字串!學習正規表示式的最好方法是從例子開始,理解例子之後再自己對例子進行修改,實驗。下面給出了不少簡單的例子,並對它們作了詳細的說明。假設你在一篇英文 裡查詢hi,你可以使用正規表示式hi。這幾乎是最簡單的正規表示式了,它可以精確匹配這樣的字串 由兩個字元組成,前乙...

正規表示式入門

字串是程式設計時涉及到的最多的一種資料結構,對字串進行操作的需求幾乎無處不在。比如判斷乙個字串是否是合法的email位址,雖然可以程式設計提取 前後的子串,再分別判斷是否是單詞和網域名稱,但這樣做不但麻煩,而且 難以復用。正規表示式是一種用來匹配字串的強有力的 它的設計思想是用一種描述性的語言來給字...