PHP 正規表示式

在本教程中,你將學習正規表示式如何工作,以及如何使用它們在 PHP 中以有效的方式執行模式匹配。

什麼是正規表示式

正規表示式,通常稱為** Regular Express** 或 RegExp,是一種特殊格式的文字字串,用於查詢文字中的模式。正規表示式是當今最有效和最有效的文字處理和操作的強大工具之一。例如,它可用於驗證使用者輸入的資料格式(即姓名,電子郵件,電話號碼等)是否正確,在文字內容中查詢或替換匹配的字串,等等。

PHP(5.3 及以上版本)通過其 preg_ 函式系列支援 Perl 樣式的正規表示式。為什麼 Perl 樣式正規表示式? 因為 Perl 是第一種為正規表示式提供整合支援的主流程式語言,因其對正規表示式及其非凡的文字處理和操作功能的強大支援而眾所周知。

在深入研究正規表示式的世界之前,我們先簡單概述一下常用的 PHP 內建模式匹配函式。

功能 它能做什麼
preg_match() 執行正規表示式匹配。
preg_match_all 執行全域性正規表示式匹配。
preg_replace() 執行正規表示式搜尋和替換。
preg_grep() 返回與模式匹配的輸入陣列的元素。
preg_split() 使用正規表示式將字串拆分為子字串。
preg_quote() 引用字串中的正規表示式字元。

注意: PHP preg_match() 函式在找到第一個匹配項後停止搜尋,而 preg_match_all() 函式繼續搜尋直到字串結尾並找到所有可能的匹配項,而不是在第一個匹配項時停止。

正規表示式語法

正規表示式語法包括使用特殊字元(不要與 HTML 特殊字元 混淆)。在正規表示式中賦予特殊含義的字元是: . * ? + [ ] ( ) { } ^ $ | \ 。每當你想要按字面意思使用它們時,你需要反斜槓這些字元。例如,如果你想匹配 .,你必須寫 \. 。所有其他字元自動採用其字面含義。

以下部分描述了可用於制定模式的各種選項:

字元類

圍繞字元圖案的方括號稱為字元類,例如 [abc] 。字元類始終匹配指定字元列表中的單個字元,這意味著表示式 [abc] 僅匹配 a,b 或 c 字元。

還可以定義否定字元類,以匹配除括號中包含的字元之外的任何字元。通過在開始括號後面放置一個插入符號(^) 來定義一個否定的字元類,就像這樣 [^abc]

你還可以使用字元類中的 - 字元來定義一系列字元,例如 [0-9] 。我們來看一些字元類的例子:

正規表示式 它能做什麼
[abc] 匹配字元 a,b 或 c 中的任何一個。
[^abc] 匹配除 a,b 或 c 之外的任何一個字元。
[a-z] 匹配從小寫 a 到小寫 z 的任何一個字元。
[A-Z] 匹配從大寫 a 到大寫 z 的任何一個字元。
[a-Z] 匹配從小寫字母 a 到大寫字母 Z 的任何一個字元。
[0-9] 匹配 0 到 9 之間的單個數字。
[a-z0-9] 匹配 a 和 z 之間或 0 到 9 之間的單個字元。

以下示例將向你展示如何使用正規表示式和 PHP preg_match() 函式查詢字串中是否存在模式 :

<?php
$pattern = "/ca[kf]e/";
$text = "He was eating cake in the cafe.";
if(preg_match($pattern, $text)){
    echo "Match found!";
} else{
    echo "Match not found.";
}
?>

同樣,你可以使用該 preg_match_all() 函式查詢字串中的所有匹配項:

<?php
$pattern = "/ca[kf]e/";
$text = "He was eating cake in the cafe.";
$matches = preg_match_all($pattern, $text, $array);
echo $matches . " matches were found.";
?>

提示: 正規表示式不是 PHP 獨有的。諸如 Java,PerlPython等語言使用相同的表示法來查詢文字中的模式。

預定義的字元類

一些字元類(如數字,字母和空格)經常使用,因此有快捷方式名稱。下表列出了這些預定義的字元類:

捷徑 它能做什麼
. 匹配除換行符 \n 之外的任何單個字元。
\d 匹配任何數字字元。與 [0-9] 一樣
\D 匹配任何非數字字元。與 [^0-9] 一樣
\s 匹配任何空白字元(空格,製表符,換行符或回車符)。與 [ \t\n\r] 一樣
\S 匹配任何非空白字元。與 [^ \t\n\r] 一樣
\w 匹配任何單詞字元(定義為 a 到 z,A 到 Z,0 到 9 和下劃線)。與 [a-zA-Z_0-9] 一樣
\W 匹配任何非單詞字元。與 [^a-zA-Z_0-9] 一樣

以下示例將向你展示如何使用正規表示式和 PHP preg_replace() 函式在字串中使用連字元字元查詢和替換空格 :

<?php
$pattern = "/\s/";
$replacement = "-";
$text = "Earth revolves around\nthe\tSun";
// Replace spaces, newlines and tabs
echo preg_replace($pattern, $replacement, $text);
echo "<br>";
// Replace only spaces
echo str_replace(" ", "-", $text);
?>

重複量詞

在上一節中,我們學習瞭如何以各種方式匹配單個字元。但是如果你想匹配多個字元怎麼辦? 例如,假設你要查詢包含字母 p 的一次或多次的單詞,或包含至少兩個 p 的單詞,依此類推。這就是量詞開始發揮作用的地方。使用量詞,你可以指定正規表示式中的字元應匹配的次數。

下表列出了量化特定模式的各種方法:

正規表示式 它能做什麼
p+ 匹配字母 p 的一次或多次出現。
p* 匹配字母 p 的零次或多次出現。
p? 匹配字母 p 的零次或一次出現。
p{2} 匹配恰好兩次出現的字母 p。
p{2,3} 匹配至少兩次出現的字母 p,但不超過三次出現的字母 p。
p{2,} 匹配字母 p 的兩次或多次出現。
p{,3} 匹配最多三次出現的字母 p

以下示例中的正規表示式將使用 PHP preg_split() 函式以逗號,逗號序列,空格或其組合拆分字串 :

<?php
$pattern = "/[\s,]+/";
$text = "My favourite colors are red, green and blue";
$parts = preg_split($pattern, $text);
 
// Loop through parts array and display substrings
foreach($parts as $part){
    echo $part . "<br>";
}
?>

位置限定錨

在某些情況下,你希望在行,單詞或字串的開頭或結尾處進行匹配。為此,你可以使用錨點。兩個常見的錨是 ^ ,它代表字串的開頭,而 $ 符號代表字串的結尾。

正規表示式 它能做什麼
^p 匹配一行開頭的字母 p。
p$ 匹配一行末尾的字母 p。

以下示例中的正規表示式將僅顯示 names 陣列中使用 PHP preg_grep() 函式以字母 J 開頭的名稱 :

<?php
$pattern = "/^J/";
$names = array("Jhon Carter", "Clark Kent", "John Rambo");
$matches = preg_grep($pattern, $names);
 
// Loop through matches array and display matched names
foreach($matches as $match){
    echo $match . "<br>";
}
?>

模式修飾符

模式修飾符允許你控制模式匹配的處理方式。模式修飾符直接放在正規表示式之後,例如,如果要以不區分大小寫的方式搜尋模式,可以使用 i 修飾符,如下所示: /pattern/i 。下表列出了一些最常用的模式修飾符。

修改 它能做什麼
i 使匹配不區分大小寫的方式。
m 更改 ^$ 的行為來匹配新行邊界(即多行字串中每行的開頭或結尾),而不是字串邊界。
g 執行全域性匹配,即查詢所有匹配項。
o 僅對表示式求值一次。
s 更改 . 的行為以匹配所有字元,包括換行符。
x 允許你在正規表示式中使用空格和註釋以便清晰。

以下示例將向你展示如何使用 i 修飾符和 PHP preg_match_all() 函式執行全域性不區分大小寫的搜尋。

<?php
$pattern = "/color/i";
$text = "Color red is more visible than color blue in daylight.";
$matches = preg_match_all($pattern, $text, $array);
echo $matches . " matches were found.";
?>

類似地,以下示例顯示如何使用 ^ 錨點和 m 修飾符與 PHP preg_match_all() 函式在多行字串中的每一行的開頭匹配。

<?php
$pattern = "/^color/im";
$text = "Color red is more visible than \ncolor blue in daylight.";
$matches = preg_match_all($pattern, $text, $array);
echo $matches . " matches were found.";
?>

詞邊界

單詞邊界字元(\b)可幫助你搜尋以模式開頭和/或結尾的單詞。例如,正規表示式 /\bcar/ 匹配以模式 car 開頭的單詞,並且匹配 cartcarrotcartoon,但不匹配 oscar

同樣,正規表示式 /car\b/ 匹配以模式 car 結尾的單詞,並且匹配 scaroscarsupercar,但不匹配 cart。同樣, /\bcar\b/ 匹配以模式 car 開頭和結尾的單詞,並且只匹配單詞 car

以下示例將突出以粗體顯示以 car 開頭的單詞:

<?php
$pattern = '/\bcar\w*/';
$replacement = '<b>$0</b>';
$text = 'Words begining with car: cart, carrot, cartoon. Words ending with car: scar, oscar, supercar.';
echo preg_replace($pattern, $replacement, $text);
?>

我們希望你已瞭解正規表示式的基礎知識。要了解如何使用正規表示式驗證表單資料,請檢視有關 [PHP 表單驗證]/zh-tw/tutorial/php/php-form-validation/) 的教程。