PHP Regex筆記,phpRegex筆記_PHP教程

來源:互聯網
上載者:User

PHP Regex筆記,phpRegex筆記


什麼是Regex

在電腦上我們經常會使用(萬用字元)找出我們需要的檔案,例如:*.doc ,這裡的 * 代表匹配零個或多個字元。Regex也是用來進行文本匹配的工具,只不過它更加強悍。引用 PHP 手冊裡的一句話:Regex是一個從左至右匹配目標字串的模式,大多數字元自身就代表一個匹配 它們自身的模式。

下面給出幾個簡單例子,使對Regex有個初步的理解。

hi  //匹配英文字元(忽略大小寫) hi , HI , Hi , hI
\bhi\b  //匹配英文單詞 hi  '\b'是正則裡的一特殊字元(一種斷言),表示單詞邊界
\bhi\b.*\bLucy\b  //匹配如:'hi my name is Lucy'  '.' 表示匹配除分行符號以外的任一字元  '*' 是量詞,表示重複零次或更多次
0\d{2}-\d{8}  //匹配如: 020-12345678  '\d' 匹配一個數字(0-9)    '{n}' 重複n次,如{2} {8}

上面例子中的 \b , . , * , \d , {2} 都有特殊含義,在下文會有說明。

PHP 中正則文法

1.簡介

在 PHP 裡支援兩種正則分別是 POSIX 和 PCRE 。自 PHP 5.3.0起,POSIX Regex擴充被廢棄。所以下文討論的都是基於 PCRE 模式。可點擊查看有關與 POSIX Regex的不同和與 perl 的不同之處。

2.分隔字元

當使用 PCRE 函數 的時候,模式需要由分隔字元閉合包裹。分隔字元可以使任意非字母數字、非反斜線、非空白字元。經常使用的分隔字元是正斜線 / 、hash符號 # 以及取反符號 ~ 。下面的例子都是使用合法分隔字元的模式。

/foo bar/#^[^0-9]$#+php+%[a-zA-Z0-9_-]%

如果分隔字元需要在模式內進行匹配,它必須使用反斜線進行轉義。如果分隔字元經常在模式內出現,一個更好的選擇就是是用其他分隔字元來提高可讀性。例:

/http:\/\//#http://#

3.元字元

Regex的威力源於它可以在模式中擁有選擇和重複的能力。一些字元被賦予特殊的含義,使其不再單純的代表自己,模式中的這種有特殊涵義的編碼字元 稱為元字元
共有兩種不同的元字元:一種是可以在模式中方括弧外任何地方使用的,另外一種是需要在方括弧內使用的。

在方括弧外使用的元字元如下:

代碼 說明
/ 一般用於逸出字元
^ 斷言目標的開始位置(或在多行模式下是行首)
$ 斷言目標的結束位置(或在多行模式下是行尾)
. 匹配除分行符號外的任何字元(預設)
[ 開始字元類定義
] 結束字元類定義
| 開始一個可選分支
( 子組的開始標記
) 子組的結束標記
? a:作為量詞,表示 0 次或 1 次匹配。b:位於量詞後面用於改變數詞的貪婪特性。
* 量詞,0 次或多次匹配
+ 量詞,1 次或多次匹配
{ 自訂量詞開始標記
} 自訂量詞結束標記

模式中方括弧內的部分稱為“字元類”。 在一個字元類中僅有以下可用元字元:

代碼 說明
\ 逸出字元
^ 僅在作為第一個字元(方括弧內)時,表明字元類取反
- 標記字元範圍

樣本:

  • \ba\w*\b 匹配以字母 a 開頭的單詞,先是某個單詞開始處 \b ,然後是字母 a ,然後是任意數量的任意單詞字元(單詞字元指的是任意字母、數字、底線) \w* ,最後是單詞結束處 \b 。
  • \d+ 匹配1個或更多連續的數字。
  • ^\d{5,12}$ 匹配為5位到12位元字,因為使用了 ^ 和 $ ,所以輸入的整個字串都要用來和 \d{5,12} 來匹配,也就是說整個輸入必須是5到12個數字。

4.逸出序列(反斜線)

反斜線 \ 有四種用法,詳細可點擊 逸出序列(反斜線)

【1】作為逸出字元,比如,如果你希望匹配一個 * 字元,就需要在模式中寫為 \* 。這適用於一個字元在不進行轉義會有特殊含義的情況下。 但是,對於非數字字母的字元,總是在需要其進行原文匹配的時候在它前面增加一個反斜線,來聲明它代表自己,這是安全的。如果要匹配一個反斜線,那麼在模式中使用 \\
反斜線在單引號字串和雙引號字串中都有特殊含義,因此要匹配一個反斜線, 模式中必須寫為 \\\\ 。其中的原因:首先它作為字串,反斜線會進行轉義。最後Regex引擎也認為反斜線是轉義。因此,需要 4 個反斜線才可以匹配一個反斜線。

【2】提供了一種對非列印字元進行可見編碼的控制手段

【3】用來描述特定的字元類

代碼 說明
\d 任意十進位數字
\D 任意非十進位數字
\h 任意水平空白字元(since PHP 5.2.4)
\H 任意非水平空白字元(since PHP 5.2.4)
\s 任意空白字元
\S 任意非空白字元
\v 任意垂直空白字元(since PHP 5.2.4)
\V 任意非垂直空白字元(since PHP 5.2.4)
\w 任意單詞字元,單詞字元指的是任意字母、數字、底線。
\W 任意非單詞字元

【4】一些簡單的斷言。一個斷言指定一個必須在特定位置匹配的條件,它們不會從目標字串中消耗任何字元。反斜線斷言包括:

  • \b 單詞邊界
  • \B 非單詞邊界
  • \A 目標的開始位置(獨立於多行模式)
  • \Z 目標的結束位置或結束處的分行符號(獨立於多行模式)
  • \z 目標的結束位置(獨立於多行模式)
  • \G 在目標中最初相符位置

5.重複/量詞

代碼 說明
* 重複零次或更多次,等價於
+ 重複一次或更多次,等價於
? 重複零次或一次,等價於
{n} 重複n次
{n,} 重複n次或更多次
{n,m} 重複n到m次

預設情況下,量詞都是”貪婪”的,也就是說,它們會在不導致模式比對失敗的前提下,儘可能多的匹配字元(直到最大允許的匹配次數)。然而,如果一個量詞緊跟著一個 ? 標記,它就會成為懶惰(非貪婪)模式, 它不再儘可能多的匹配,而是儘可能少的匹配。
下面直接看樣本,理解“貪婪”和“非貪婪”模式是怎麼回事。

對於字串 "aatest1bbtest2cc"Regex ".*"    匹配結果 "test1bbtest2"Regex ".*?"   匹配結果 "test1"

關於更多“貪婪”和“非貪婪”模式的介紹可查閱 http://php.net/manual/zh/regexp.reference.repetition.php

6.字元類(方括弧)

PHP手冊中的描述:

  • 左方括弧開始一個字元類的描述,並以方中括弧結束。單獨的一個右方括弧沒有特殊含義。如果一個右方括弧需要作為一個字元類中的成員,那麼可以將它寫在字元類的首字元處(如果使用了 ^ 取反,那麼是第二個)或者使用轉義符。

  • 一個字元類在目標字串中匹配一個單獨的字元;該字元必須是字元類中定義的字元集合的其中一個, 除非使用了 ^ 對字元類取反。如果^需要作為一個字元類的成員,確保它不是該字元類的首字元,或者對其進行轉義即可。

樣本:

[aeiou]    //匹配所有的小寫母音字母[^aeiou]   //匹配所有非母音字母的字元[.?!]      //匹配標點符號(.或?或!)

注意:^ 只是一個通過枚舉指定那些不存在字元類之中的字元的便利符號。而不是斷言, 它仍然會從目標字串中消耗一個字元,並且如果當前匹配點在目標字串末尾, 匹配將會失敗。

輕鬆地指定一個字元範圍,範圍操作以 ASCII 整理排序。它們可以用於為字元指定數值,比如 [\000-\037]

[0-9]    //代表的含意與 '\d' 就是完全一致的[a-z0-9A-Z_]    //完全等同於 '\w' 如果只考慮英文的話

下面是一個更複雜的運算式 \(?0\d{2}[) -]?\d{8}
這個運算式可以匹配幾種格式的電話號碼,像 (010)88886666,或 022-22334455 ,或 02912345678 等。
簡單分析:首先是一個逸出字元 \( ,它能出現 0 次或 1 次 ? ,然後是一個數字 0 ,後面跟著 2 個數字 \d{2} ,然後是 )- 或 “空格” 中的一個,它出現 0 次或 1 次,最後是 8 個數字 \d{8}

7.分支 ( | )

豎線字元用於分離模式中的可選路徑。比如模式 gilbert|Sullivan 匹配 ”gilbert” 或者 ”sullivan”。豎線可以在模式中出現任意多個,並且允許有空的可選路徑(匹配Null 字元串)。匹配的處理從左至右嘗試每一個可選路徑,並且使用第一個成功匹配的。如果可選路徑在子組(下面定義)中,則”成功匹配”表示同時匹配了子模式中的分支以及主模式中的其他部分。

回看上文裡的一個例子 \(?0\d{2}[) -]?\d{8} 這個正則也能匹配 010)12345678 或 (022-87654321 這樣的 “不正確” 的格式。其實我們可以利用分支就能解決這個問題,如下:

\({1}0\d{2}\){1}[- ]?\d{8}|0\d{2}[- ]?\d{8} 這個運算式匹配 3 位區號的電話號碼,其中區號可以用小括弧括起來,也可以不用,區號與本地號間可以用連字號或空格間隔,也可以沒有間隔。

使用分枝條件時,要注意各個條件的順序

8.內部選項設定

Regex在不同的模式修飾符下匹配出的結果有可能不相同。它的文法是 :(?修飾符)

比如,(?im) 設定表明多行大小寫不敏感匹配。同樣可以用它來取消這些設定,比如 (?im-sx) 設定了 “PCRE_CASELESS”,”PCRE_MULTILINE”,但是同時取消了 “PCRE_DOTALL” 和 “PCRE_EXTENDED”。如果一個字母即出現在 - 之前, 也出現在 - 之後,這個選項被取消設定。

下面緊例舉簡單的樣本,想要瞭解更多可點擊 內部選項設定 和 模式修飾符

樣本:/ab(?i)c/ 僅僅匹配 ”abc” 和 ”abC”

9.子組(子模式)

子組通過圓括弧分隔界定,並且它們可以嵌套。

樣本:

字串:"the red king"Regex:((red|white) (king|queen))匹配結果:array("red king", "red king", "red", "king")描述:其中第 0 個元素是整個模式比對的結果,後面的三個元素依次為三個子組匹配的結果。 它們的下標分別為 1, 2, 3。

經常我們會有一種需求需要使用子組進行分組,但又不需要(單獨的)捕獲它們。在子組定義的左括弧後面緊跟字串 ?: 會使得該子組不被單獨捕獲,並且不會對其後子組序號的計算產生影響。例如:

字串:"the red king"Regex:((?:red|white) (king|queen))匹配結果:array("red king", "red king", "king")

為了方便簡寫,如果需要在非捕獲子組開始位置設定選項, 選項字母可以位於 ?: 之間,比如:

(?i:saturday|sunday)(?:(?i)saturday|sunday)

上面兩種寫法實際上是相同的模式。因為可選分支會從左至右嘗試每個分支,並且選項沒有在子模式結束前被重設,並且由於選項的設定會穿透對後面的其他分支產生影響,因此, 上面的模式都會匹配 ”SUNDAY” 以及 ”Saturday”。

再看一個匹配 IP 位址的正則 ((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)
相關文章 IP地址的Regex

結語

上文中涉及 PHP Regex中常用的文法,有的文法沒細說和涉及到的,如:模式修飾符、後向引用、斷言、遞迴模式,等。你可以通過 PHP 手冊查看這些內容。

提示:一般而言,對於同樣的功能,Regex函數運行效率要低於字串函數。如果應用程式較簡單,那麼就用字串運算式。但是,對於可以通過單個Regex執行的任務來說,如果使用多個字串函數,則是不對的。 ---- 摘自《PHP 和 MySQL Web 開放》一書。

參考資料

http://php.net/manual/zh/book.pcre.php
https://msdn.microsoft.com/zh-cn/library/d9eze55x%28v=vs.80%29.aspx
http://deerchao.net/tutorials/regex/regex.htm
http://tool.chinaz.com/regex/
http://www.regexlab.com/zh/regref.htm

http://www.bkjia.com/PHPjc/1091264.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/1091264.htmlTechArticlePHP Regex筆記,phpRegex筆記 什麼是Regex 在電腦上我們經常會使用(萬用字元)找出我們需要的檔案,例如: *.doc ,這裡的...

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.