預設量詞 *、+、?、{m,n} 皆為「貪婪」,嘗試匹配最長字串。經典問題:匹配 C 註解 /* ... */。
/*first*/ not comment /*second*/
模式 /\*.*\*/ 會匹配整行 (含中間的 not comment)。
在量詞後加 ? 變非貪婪:/\*.*?\*/ 僅匹配最短區段。
修飾字 /U 可反轉整個模式預設貪婪行為,但與 ? 同時出現會相互抵消。
$str = "asdf/*asdfaldsfasdf*/asfdasldf;kfldsj*/asfddsaf";
// 非貪婪
preg_match('/\*.*?\*/', $str, $m); // 匹配 /*asdfaldsfasdf*/
// 貪婪
preg_match('/\*.*\*/', $str, $m); // 匹配整個長字串
// /U 修飾字
preg_match('/\*.*\*/U', $str, $m); // 同非貪婪
斷言不消耗字元,僅檢查位置前後是否符合條件。
\w+(?=;) // 匹配分號前的單字,不含分號
foo(?!bar) // 匹配不被 "bar" 跟隨的 "foo"
注意:(?!foo)bar 無意義,因斷言在 bar 前檢查,實際應寫 (? (向後否定)。
(?<=\$)\d+ // 匹配 $ 符號後的數字
(?
注意:foo(? 無意義,向後斷言必須放在目標字元前。
| 語法 | 名稱 | 方向 | 含義 |
|---|---|---|---|
(?=pattern) | 向前肯定 | 前 | 後面符合 pattern |
(?!pattern) | 向前否定 | 前 | 後面不符合 pattern |
(?<=pattern) | 向後肯定 | 後 | 前面符合 pattern |
(? | 向後否定 | 後 | 前面不符合 pattern |