PHP正規表達式比對

吳青澤
verybuy-dev
Published in
7 min readApr 29, 2018

有時候我們會需要過濾一些字串、或是驗證資料的情況,就可以使用 php 的正則表達式來幫助檢查,進而達到想要取得或是想要濾掉的文字部分,以下簡單介紹 Perl 函式以及正則需要用到的規則。

正則運算基本語法

下面介紹的正則運算式也稱為「 Perl 相容正則運算式( Perl Compatible Regular Express 簡稱 PCRE)」,是因為最早在 Perl平台下的regex庫,後來大家也跟著一起使用,逐漸變成一個標準,以下是基本的語法。

Perl 正則運算函數使用

透過上表的規則,可以明確需要的字串樣式、規則,進而驗證用戶輸入是否符合特定的模式,或者取代、分割成需要的文字,以下介紹相關函數。

1.preg_mtach()

用來做運算式的匹配,格式為:

" preg_match( $pattern, $subject, $matches , $flags, $offset) "

$pattern 放要比對的格式或標準,$subject 為要比對的字串,$matches 為可選,會把匹配結果存入陣列中,$matches[1] 是匹配第一個括弧的文字、$mtaches[2] 則為匹配第二個括弧內的文字,以此類推,$flags 可以選擇常數 PREG_OFFSET_CAPTURE ,設定後會導致搜索字串偏移, $offset 將會從設定的偏移量開始搜索,另外preg_match最後會回傳true、false當作比對結果,用來檢測是否滿足條件。

<?php $pattern = "/(^886\-)\d{2,3}\-\d{7,8}$/";
$string = "886-09-12345678";
preg_match($pattern, $string, $matches);
echo $matches[0]; // 886-09-123345678
echo $matches[1]; // 886-
?>

可以發現 $matches[1]就是第一個括弧內所要比對的字串。

2.preg_match_all()

“ preg_match_all( $pattern, $subject, $matches , $flags, $offset ) “

與 preg_match 是相同用法,用來匹配正則運算式,語法格式也相同,區別在於 preg_mtach 一旦搜索到結果,會停止繼續往下而回傳結果,但是 preg_mtach_all 會一直搜尋到$subject的結尾,找到第一個匹配的文字後,下次會從第一個匹配結果往下繼續搜索。

<?php$pattern = "/\w+/";
$string = "Hello this is test";
preg_match($pattern, $string, $matches);
foreach ($matches[0] as $word) {
echo $word . PHP_EOL;
}
?>// result/*
Hello
this
is
test
*/

如果使用同樣的方式使用 preg_match 的結果就會是只有 "Hello",因為一旦找到符合的字串,就會立即回傳。

3.preg_replace()

用來做正則運算的搜索以及取代,格式為:

“preg_replace( $pattern, $replacement, $subject, $limit)”

$pattern 為所要匹配的規則與前面相同,$replacement 是搜索相關字詞後所要取代成為的文字,$subject 則為要進行比對的文字內容, 設定 $limit 參數代表只取代 $limit 個匹配(ex: $limit = 2的話,只取代前兩個匹配的文字)

<?php$pattern = "/\s/";
$string = "Hello this is test";
$result = preg_replace($pattern, "-", $string);
echo $result; // Hello-this-is-test
$result1 = preg_replace($pattern, "-", $string, 1);
echo $result1; // Hello-this is test
?>

如果 $limit 參數設定 -1,則代表所以有的匹配都會被取代,其實就跟沒設定一樣意思。

4.preg_split()

該函數用來分割字串,格式為:

“preg_split( $pattern, $subject, $limit, $)”

將 $subject 依照規則切開後,組成一個陣列回傳,設定 $limit 參數,只會回傳 $limit 個結果(ex: $limit = 2 回傳前兩個匹配結果),如果是-1或者未設定,就是代表回傳所以匹配結果。

<?php$pattern = "/-/";
$string = "Hello-this-is-test";
$result = preg_split($pattern, $string);
print_r($result);
?>// result
/*
Array
(
[0] => Hello
[1] => this
[2] => is
[3] => test
)
*/

有其他更容易且簡單的函數可以使用,例如 explode()和 str_split()等等...

5.preg_grep()

用來做正則運算的匹配與回傳陣列,格式為:

"preg_grep ($pattern , $input_array, $flags)"

$pattern是要比對的正則規則,$input_array 是所要比對的陣列或是輸入的陣列,$flags是可選擇參數( PREG_GREP_INVERT)

<?php$pattern = "/e/";
$array = array("Hello", "this", "is", "test");
$result = preg_grep($pattern, $string);
print_r($result);
?>// result
/*
Array
(
[0] => Hello
[3] => test
)
*/

使用常數 PREG_GREP_INVERT 的結果為與 $pattern 不相匹配的文字,就是與上面例子剛好相反,回傳結果為

Array
(
[1] => this
[2] => is
)

最後附上幾個表單資料常需要驗證的格式

1.email

首先要把email分成XXX(用戶名)@XXX(伺服器名)兩部份,用戶名包含英文數字符號等等(寫成”^[\w-]+$”),但不能以點作為開始、結尾(“.”),所以再加上修改變成(^[\w-]+(\.[\w-]+$*)完成左半邊用戶名檢查,後面伺服器名也是相同道理,所以最後會得到(“^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$”)的正則表達式。

2.手機號碼

台灣手機為09XXXXXXXX,所以使用(“⁰⁹”)來限定09開頭,接下來後面8位數皆為數字所以使用(“[0–9]{8}”),所以加起來會得到(“⁰⁹[0–9]{8}”)。

3.URL網址:

網址格式為http://xxx.xxx.xxx諸如此類,所以開頭使用("^http:\/\/"),再來中間的("[\w-]+\.+[\w-]"),最後式後面參數的部份("[\w- ./?%&=]”),合起來便是(“^http:\/\/([\w-]+\.)+[\w-]+([\w- ./?%&=]*)?”)。

4.IP位址:

IP位址格式為xxx.xxx.xxx.xxx,所以用正整數比對加上句點(“.”),記得加上避開字元即可(“\”),所以就會得到”(\d+)\.(\d+)\.(\d+)\.(\d+)”。

結論

正則運算式的組合五花八門,不太可能所有規則都記清楚,基本的語法與規則掌握好,剩下複雜且客製化的需求,就是需要點時間去try try看了。

--

--