天天看點

正規表達式基礎

正規表達式基礎,一些基本符号和表達式的使用,附有參考連結和測試工具連結.

正規表達式基礎

正規表達式定義

     正規表達式,Regular Expression,也常被簡寫為regex,regexp或RE.

     通常用一個正規表達式描述一個特征,然後去驗證其他字元串是否符合這個特征.

     正規表達式也常被稱作一個模式(pattern).

     PS:正規表達式精确的文法可能會因程式語言或工具的不同而有所差異.

     PPS:本文是學習之記錄,如有不妥還望指正.

普通字元和特殊字元

     字元分為普通字元和特殊字元.

     特殊字元也被稱為元字元.

     普通字元比對與自身完全相同的一個字元,如字母,數字等.

     什麼樣的字元叫普通字元呢?除了特殊的,就是普通的,是以本文後面提到的都是特殊的.

     通常有一些表可以查詢:

     http://msdn.microsoft.com/zh-cn/library/az24scfc.aspx

     http://msdn.microsoft.com/zh-cn/library/ae5bf541(v=vs.100).aspx

     如何表示特殊符号本身?

     特殊字元前面加反斜杠(\)時表示自身.比如特殊字元^,$等,前面加上\,就表示這個符号本身.

     (可能正反斜杠不太容易記憶,是以可以記為右手斜杠).

     \就是轉義字元,普通加轉義變成特殊的,如\d;特殊加轉義變成普通的,如\$.

常用元字元

     \d比對一位數字.(因為它是digit的首字母).

     \w比對字母或數字或下劃線或漢字等.(聯想tip:可能是”字”word的首字母).

     \s比對任意的空白符,包括空格,Tab,換行.(可能因為是space的首字母).

     \b代表單詞分界處(比如空格,标點符号和換行等),\b不比對這些符号,隻比對一個位置.(這個想不出為什麼了,難道是begin?blank?).

     .比對除了換行之外的任意字元.

     上面幾個常用元字元的大寫字母形式則是其反義,比如\D比對任意非數字的字元,其他\W,\S,\B的意思可以類推.

     一些不便被表示的符号(非列印字元)用轉義字元表示,如:

     \r,\n代表回車和換行符.

     \t代表制表符.

字元集 (中括号[]的使用)

     字元集合用方括号組織.

     []中可以羅列元素,如[aeiou]比對任何一個原因字母.[]中可以包含任意多個字元,可以比對其中任意一個,但是隻能是一個.

     [^]是反向字元集,如[^xyz]比對除了xyz之外的任意一個字元.

     正反向的字元集都可以劃定範圍.比如[0-9][0-9a-z][^A-F0-3]等等.

     但是永遠要記得:不管方括号[]裡面有多少内容,它永遠都隻比對一個字元作為比對内容.

     要比對多個字元,需要用數量限定符.

分組 (小括号()的使用)

     中括号介紹完了之後就是小括号了.

     小括号是用來分組的, ()符号:

     1.在被修飾比對次數的時候,括号中的表達式可以作為整體被修飾;

     2.取比對結果的時候,括号中的表達式比對到的内容可以被單獨得到.

     總而言之,小括号标記了子表達式的開始和結尾,可以儲存子表達式以備将來之用.

     小括号的另一種用途是通過文法(?#comment)來包含注釋.

指定數量的限定符 (大括号{}用在這裡)

     *代表前面的内容出現0次到多次.

     +代表前面的内容出現1次到多次.

     ?代表前面的内容出現0次或1次.

     {n}代表前面的内容重複n次(不能多也不能少).

     {n,}代表前面的内容重複n次或更多次.

     {n,m}代表前面的内容重複n到m次.

     正規表達式預設是貪婪比對,即比對盡可能多的字元,比如a.*b它會比對以a開始,以b結束的最長的字元串.

     但是有時候我們需要懶惰比對(非貪婪比對),也即比對盡可能少得字元,要實作這個效果,隻要在數量限定符的後面跟上一個問号?.

  這樣a.*?b會比對以a開始,以b結束的最短的字元串.

比對

    一般的正則比對:當被檢測的字元串包含的某個部分符合正規表達式的描述時,稱為比對成功;符合比對的部分即是比對到的内容. 

     但是如果加上^和$限定比對字元串的開頭和結尾,則必須是整個字元串比對,比對才能成功.

     比如\d是表示數字,\d{5,12}隻能保證字元串裡包含5到12連續位數字,而^\d{5,12}&則保證整個字元串就是5到12位數字.

     ^,$和\b都是用來進行邊界比對的,它們本身并不比對任何字元.

分支條件

     用|可以把不同的規則分隔開.左右兩邊表達式是或的關系,即比對左邊或者右邊,可以在多個項之間進行選擇.

     比對分支條件時會采取短路原則,即如果前面某個分支已經滿足,則不會再測試後面的分支條件.

後向引用

     前面介紹的小括号的使用,用來分組,以備後續使用,這裡就要介紹怎麼使用.

     表達式在比對的時候,會将小括号包含的表達式所比對到的字元串記錄下來,在擷取比對結果的時候,小括号表達式比對的字元串可以單獨擷取.

     小括号比對到的字元串,不僅是在比對結束後才能使用,在比對過程中也可以使用.

     這樣就可以比對重複出現的單詞等.

     表達式後面的部分,可以引用前面”括号内的子比對已經比對到的字元串”,引用方法是反斜杠\加上一個數字.

     \1引用第一對括号内比對到的字元串, \2引用第二對. 比較特殊的是分組0對應整個正規表達式.

     如果有嵌套的括号,則外層的括号先排序号(即按照左括号的順序排序).

     也可以自己指定子表達式的組名,文法是:(?<name>exp),其中<>換成單引号也行.

     引用自己指定名字的子表達式:\k<name>

     組号配置設定時掃描兩遍,第一遍給未命名的組配置設定,第二遍給命名了的組配置設定組号.

     使用(?:exp)将不捕獲比對的文本,也不給此組配置設定編号.

零寬斷言和負向零寬斷言

     斷言指定了一個條件(可能是正向條件或者負向條件),然後零寬表示所占寬度為零,即自身并不被包含在比對結果裡,就好像\b,^,$等.

     兩個正向條件的, 即零寬斷言:

     (?=exp)零寬度正預測先行斷言,它斷言自身出現的位置後面能比對表達式exp.

          比如\b\w+(?=ing\b),比對以ing結尾的單詞的前面部分.

     (?<=exp)零寬度正回顧後發斷言,它斷言自身出現的位置的前面能比對表達式exp.

          比如(?<=\bre)\w+\b會比對以re開頭的單詞的後半部分.

     兩個負向條件的, 即負向零寬斷言:

     (?!exp)零寬度負預測先行斷言,斷言此位置的後面不能比對表達式exp.

          比如\d{3}(?!\d)比對三位數字,而且這三位數字的後面不能是數字.

     (?<!exp)零寬度負後顧後發斷言,斷言此位置的前面不能比對表達式exp.

          比如(?<![a-z]\d{7})比對前面不是小寫字母的七位數字.

參考資料

     正規表達式30分鐘入門教程:

     http://deerchao.net/tutorials/regex/regex.htm

     wikipedia:

     http://zh.wikipedia.org/wiki/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F

     揭開正規表達式的神秘面紗:

     http://www.regexlab.com/zh/regref.htm

     msdn正規表達式文法:

     http://msdn.microsoft.com/zh-cn/library/az24scfc.aspx

     正規表達式測試網站:

     多種語言的正規表達式線上測試:

     http://www.regexplanet.com/

     JavaScript正則測試:

     http://regexpal.com/

     regex101:

     https://www.regex101.com/

     正規表達式狀态機生成器:

     https://www.debuggex.com/

作者: 聖騎士Wind

出處: 部落格園: 聖騎士Wind

Github: https://github.com/mengdd

微信公衆号: 聖騎士Wind

正規表達式基礎

繼續閱讀