PHP 正則表達式預設使用貪婪模式,會嘗試匹配盡可能長的字串。透過在量詞後加上 ? 可切換為非貪婪模式(又稱懶惰模式),匹配盡可能短的字串。本文透過實例詳細說明兩者差異與應用場景。
<?php
$str = "https://www.baidu/.com?url=www.sina.com/";
preg_match("/http:(.*)com/", $str, $matches);
print_r($matches);
結果:
Array
(
[0] => https://www.baidu/.com?url=www.sina.com
[1] => //www.baidu/.com?url=www.sina.
)
.* 匹配了從 http: 後到最後一個 com 之間的所有內容。
<?php
$str = "https://www.baidu/.com?url=www.sina.com/";
preg_match("/http:(.*?)com/", $str, $matches);
print_r($matches);
結果:
Array
(
[0] => https://www.baidu/.com
[1] => //www.baidu/.
)
.*? 在 http: 後匹配最少字元 直到遇到第一個 com 即停止。
| 貪婪量詞 | 非貪婪量詞 | 說明 |
|---|---|---|
* | *? | 匹配 0 次或多次 |
+ | +? | 匹配 1 次或多次 |
? | ?? | 匹配 0 次或 1 次 |
{n,} | {n,}? | 至少匹配 n 次 |
{n,m} | {n,m}? | 匹配 n 到 m 次 |
/.*?<\/div>/s 正確提取單個 div 區塊,避免匹配到最後一個閉合標籤
- JSON/字串解析:
/".*?"/ 正確匹配雙引號包圍的字串
- URL 參數擷取:
/param=.*?&/ 精確取得單一參數值
效能考量
非貪婪模式在某些情況下可能較慢(需回溯),但對於精確匹配需求不可或缺。複雜正則建議使用 preg_match_all() 並搭配具體邊界字元(如引號、標籤)而非通配符。
進階技巧:佔有優先量詞
PHP 支援 *+、++、?+ 等佔有優先量詞(具體支援視 PCRE 版本),一旦匹配不回溯,效能更佳但靈活度較低。
- 上一篇文章: ThinkPHP 表單提交自動轉義問題完整解決方案
- 下一篇文章: PHP in_array() 函數型別比較陷阱與最佳實踐