快速入門
教學
工具和語言
範例
參考
書籍評論
正規表示式工具
grep
PowerGREP
RegexBuddy
RegexMagic
一般應用程式
EditPad Lite
EditPad Pro
語言和函式庫
Boost
Delphi
GNU (Linux)
Groovy
Java
JavaScript
.NET
PCRE (C/C++)
PCRE2 (C/C++)
Perl
PHP
POSIX
PowerShell
Python
R
Ruby
std::regex
Tcl
VBScript
Visual Basic 6
wxWidgets
XML Schema
Xojo
XQuery 和 XPath
XRegExp
資料庫
MySQL
Oracle
PostgreSQL
本網站的更多資訊
簡介
正規表示式快速入門
正規表示式教學
替換字串教學
應用程式和語言
正規表示式範例
正規表示式參考
替換字串參考
書籍評論
可列印 PDF
關於本網站
RSS Feed 和部落格
RegexBuddy—The best regex editor and tester for PHP developers!

PHP 提供三組正規表示式函式

PHP 是一種用於製作動態網頁的開源語言。PHP 有三組函式,可讓您使用 正規表示式

最重要的正規表示式函式組以 preg 開頭。這些函式是 PCRE 函式庫 (Perl 相容正規表示式) 的 PHP 封裝。在本網站的 正規表示式教學 中,關於 PCRE 正規表示式特性的任何說明都適用於 PHP 的 preg 函式。當教學特別提到 PHP 時,假設您使用的是 preg 函式。對於所有使用正規表示式的新 PHP 程式碼,您都應該使用 preg 函式。從 PHP 4.2.0 (2002 年 4 月) 開始,PHP 預設包含 PCRE。

最舊的正規表示式函式組是以 ereg 開頭的函式。它們實作 POSIX 延伸正規表示式,就像傳統的 UNIX egrep 指令。這些函式主要用於與 PHP 3 的向下相容性。從 PHP 5.3.0 開始,它們已正式棄用。許多較新的正規表示式功能,例如 惰性量詞環顧Unicode,都不受 ereg 函式支援。不要被「延伸」這個名稱所迷惑。POSIX 標準是在 1986 年定義的,而正規表示式從那時以來已經有了很大的進展。

最後一組是 ereg 組的變體,在函數名稱前加上「多位元組」的 mb_ 前綴。雖然 ereg 將 regex 和主旨字串視為一系列 8 位元字元,但 mb_ereg 可以處理來自各種編碼頁的多位元組字元。如果您希望您的 regex 將遠東字元視為個別字元,則您需要使用 mb_ereg 函數,或使用帶有 /u 修飾詞的 preg 函數。 mb_ereg 在 PHP 4.2.0 及後續版本中提供。它使用相同的 POSIX ERE 風格。

preg 函數組

所有 preg 函數都要求您使用 Perl 語法將正規表示式指定為字串。在 Perl 中,/regex/ 定義正規表示式。在 PHP 中,這會變成 preg_match('/regex/', $subject)。當正斜線用作 regex 分隔符號時,正規表示式中的任何正斜線都必須用反斜線跳脫。因此 https://www\.jgsoft\.com/ 會變成 '/https:\/\/www\.jgsoft\.com\//'。就像 Perl 一樣,preg 函數允許任何非字母數字字元作為 regex 分隔符號。使用百分比符號作為 regex 分隔符號,URL regex 會更具可讀性,例如 '%https://www\.jgsoft\.com/%',因為這樣您不需要跳脫正斜線。如果 regex 中包含任何百分比符號,您必須跳脫這些符號。

與 C# 或 Java 等程式語言不同,PHP 不需要跳脫字串中的所有反斜線。如果您要在 PHP 字串中包含反斜線作為文字字元,則只有在反斜線後跟隨另一個需要跳脫的字元時,才需要跳脫反斜線。在單引號字串中,只有單引號和反斜線本身需要跳脫。這就是為什麼在上述 regex 中,我不必在文字句點前面加倍反斜線。regex \\ 用於匹配單個反斜線,將會變成 PHP preg 字串 '/\\\\/'。除非您要在正規表示式中使用變數內插,否則您應該始終在 PHP 中使用單引號字串表示正規表示式,以避免反斜線的混亂重複。

要指定 regex 匹配選項(例如不區分大小寫),其指定方式與 Perl 中相同。 '/regex/i' 以不區分大小寫的方式套用 regex。 '/regex/s' 使 匹配所有字元。 '/regex/m' 使 行首和行尾錨點 匹配主旨字串中的內嵌換行符。 '/regex/x' 開啟 自由間距模式。您可以指定多個字母來開啟多個選項。 '/regex/misx' 開啟所有四個選項。

一個特殊的選項是 /u,它會開啟 Unicode 比對模式,而不是預設的 8 位元組比對模式。您應該為使用 \x{FFFF}\X\p{L} 來比對 Unicode 字元、字位、屬性或腳本的正規表示式指定 /u。PHP 會將 '/regex/u' 解釋為 UTF-8 字串,而不是 ASCII 字串。

ereg 函式一樣,bool preg_match (string pattern, string subject [, array groups]) 如果正規表示式模式與 subject 字串或 subject 字串的一部分相符,則傳回 TRUE。如果您指定第三個參數,preg 會將由第一個 擷取群組 比對到的子字串儲存在 $groups[1] 中。 $groups[2] 會包含第二個配對,依此類推。如果 regex 模式使用 命名擷取,您可以使用 $groups['name'] 根據名稱存取群組。 $groups[0] 會保留整體比對。

int preg_match_all (string pattern, string subject, array matches, int flags) 會以 subject 字串中正規表示式模式的所有比對來填滿陣列 “matches”。如果您指定 PREG_SET_ORDER 作為旗標,則 $matches[0] 是包含第一個比對的比對和反向參照的陣列,就像 $groups 陣列由 preg_match 填滿一樣。 $matches[1] 保留第二個比對的結果,依此類推。如果您指定 PREG_PATTERN_ORDER,則 $matches[0] 是包含完整連續 regex 比對的陣列,$matches[1] 是包含所有比對的第一個反向參照的陣列,$matches[2] 是包含每個比對的第二個反向參照的陣列,依此類推。

array preg_grep (string pattern, array subjects) 傳回一個陣列,其中包含陣列 “subjects” 中所有可以由正規表示式模式比對到的字串。

mixed preg_replace (mixed pattern, mixed replacement, mixed subject [, int limit]) 傳回一個字串,其中 subject 字串中 regex 模式的所有比對都已用 replacement 字串取代。最多會進行 limit 次取代。一個關鍵的差異是,除了 limit 之外,所有參數都可以是陣列,而不是字串。在這種情況下,preg_replace 會執行其工作多次,同時反覆處理陣列中的元素。您也可以對某些參數使用字串,對其他參數使用陣列。然後,函式會反覆處理陣列,並對每次反覆處理使用相同的字串。使用模式和取代的陣列,讓您可以在單一 subject 字串上執行一系列的搜尋和取代作業。對 subject 字串使用陣列,讓您可以在多個 subject 字串上執行相同的搜尋和取代作業。

preg_replace_callback (混合模式、回呼替換、混合主旨 [, int 限制]) 的運作方式與 preg_replace 相同,但第二個參數使用回呼,而不是字串或字串陣列。回呼函式會針對每個相符項呼叫。回呼應接受單一參數。此參數會是一個字串陣列,元素 0 包含整體正規表示式相符項,而其他元素則包含由擷取群組相符的文字。這與您從 preg_match 取得的陣列相同。回呼函式應傳回相符項應替換的文字。傳回空字串以刪除相符項。傳回 $groups[0] 以略過此相符項。

回呼讓您可以執行強大的搜尋和替換作業,而這是僅使用正規表示式無法做到的。例如,如果您搜尋正規表示式 (\d+)\+(\d+),您可以使用回呼將 2+3 替換為 5

function regexadd($groups) {
  return $groups[1] + $groups[2];
}

陣列 preg_split (字串模式、字串主旨 [, int 限制]) 的運作方式與 split 相同,但它使用 Perl 語法作為正規表示式模式。

請參閱 PHP 手冊以取得有關 preg 函式組的更多資訊

ereg 函式組

ereg 函式要求您將正規表示式指定為字串,正如您所預期的。 ereg('regex', "subject") 檢查 regex 是否與 subject 相符。傳遞正規表示式作為文字字串時,您應使用單引號。幾個 特殊字元(如美元符號和反斜線)在雙引號 PHP 字串中也是特殊字元,但在單引號 PHP 字串中則不是。

int ereg (字串模式、字串主旨 [, 陣列群組]) 如果正規表示式模式與主旨字串或主旨字串的一部分相符,則傳回相符項的長度;否則傳回零。由於零會評估為 False,而非零會評估為 True,因此您可以在 if 陳述式中使用 ereg 來測試相符項。如果您指定第三個參數,ereg 會將正規表示式第一對 圓括號 之間的部分所相符的子字串儲存在 $groups[1] 中。 $groups[2] 會包含第二對,依此類推。請注意,ereg 不支援僅分組的圓括號。 ereg 區分大小寫。 eregi 是不區分大小寫的等效函式。

字串 ereg_replace (字串模式、字串替換、字串主旨) 會將主旨字串中正規表示式模式的所有相符項替換為替換字串。您可以在替換字串中使用 反向參照\\0 是整個正規表示式相符項,\\1 是第一個反向參照,\\2 是第二個,依此類推。最高的反向參照為 \\9ereg_replace 區分大小寫。 eregi_replace 是不區分大小寫的等效函式。

陣列 split (字串 pattern, 字串 subject [, 整數 limit]) 使用正則表示式 pattern 將 subject 字串分割成陣列。陣列將包含正則表示式比對之間的子字串。實際比對到的文字將會被捨棄。如果您指定一個限制,結果陣列將最多包含這麼多子字串。subject 字串將最多被分割 limit-1 次,陣列中的最後一個項目將包含 subject 字串中未分割的剩餘部分。 split 區分大小寫。 spliti 是不區分大小寫的等效函數。

請參閱 PHP 手冊以取得有關 ereg 函數集的更多資訊

mb_ereg 函數集

mb_ereg 函數與 ereg 函數的工作方式完全相同,只有一個關鍵差異:ereg 將正則表示式和 subject 字串視為一系列 8 位元元組,而 mb_ereg 可以處理來自各種編碼頁的多位元元組。例如,使用 Windows 編碼頁 936 (簡體中文) 編碼的字詞 中国(「中國」)包含四個位元元組:D6D0B9FA。對此字串使用正則表示式 . 的 ereg 函數會產生第一個位元元組 D6 作為結果。點號比對到一個位元元組,因為 ereg 函數是以位元元組為導向。在呼叫 mb_regex_encoding("CP936") 之後使用 mb_ereg 函數會產生位元元組 D6D0 或第一個字元 作為結果。

為確保您的正則表示式使用正確的編碼頁,請呼叫 mb_regex_encoding() 來設定編碼頁。如果您沒有這麼做,將改用 mb_internal_encoding() 回傳或設定的編碼頁。

如果您的 PHP 程式碼使用 UTF-8,您可以使用 preg 函數搭配 /u 修飾詞來比對多位元元組 UTF-8 字元,而不是個別位元元組。 preg 函數不支援任何其他編碼頁。

請參閱 PHP 手冊以取得有關 mb_ereg 函數集的更多資訊

進一步閱讀

Mastering Regular Expressions這本 Mastering Regular Expressions 不僅解釋了您想了解和不想了解的關於正則表示式的一切。它還有一個關於 PHP preg 函數集的精彩章節,其中包含有關底層 PCRE 正則表示式引擎的詳細資訊,以及大量展示更進階技術的範例 PHP 程式碼。本書不包含 ereg 和 mb_ereg 函數集。

我對 Mastering Regular Expressions 一書的評論

| 快速入門 | 教學 | 工具和語言 | 範例 | 參考 | 書籍評論 |

| grep | PowerGREP | RegexBuddy | RegexMagic |

| EditPad Lite | EditPad Pro |

| Boost | Delphi | GNU (Linux) | Groovy | Java | JavaScript | .NET | PCRE (C/C++) | PCRE2 (C/C++) | Perl | PHP | POSIX | PowerShell | Python | R | Ruby | std::regex | Tcl | VBScript | Visual Basic 6 | wxWidgets | XML Schema | Xojo | XQuery 和 XPath | XRegExp |

| MySQL | Oracle | PostgreSQL |