這段php正規表示式preg_match為什麼有時候會return false?

WBOY
發布: 2016-09-19 09:16:24
原創
1156 人瀏覽過

如題:

<code class="php">echo var_dump(preg_match('/^(([a-zA-Z0-9]+\-?)+[a-zA-Z0-9]+\.)+[a-zA-Z]+$/i','lo-n.l-on.loh-4va.ccccc5om'));//return 0
echo var_dump(preg_match('/^(([a-zA-Z0-9]+\-?)+[a-zA-Z0-9]+\.)+[a-zA-Z]+$/i','lo-n.l-on.loh-4va.cccccom'));//return 1
echo var_dump(preg_match('/^(([a-zA-Z0-9]+\-?)+[a-zA-Z0-9]+\.)+[a-zA-Z]+$/i','lon.lon.lon.loh4va.cccc5com'));//return false
echo var_dump(preg_match('/^(([a-zA-Z0-9]+\-?)+[a-zA-Z0-9]+\.)+[a-zA-Z]+$/i','lon.lon.lon.loh4va.cccccom'));//return 1</code>
登入後複製
登入後複製

回覆內容:

如題:

<code class="php">echo var_dump(preg_match('/^(([a-zA-Z0-9]+\-?)+[a-zA-Z0-9]+\.)+[a-zA-Z]+$/i','lo-n.l-on.loh-4va.ccccc5om'));//return 0
echo var_dump(preg_match('/^(([a-zA-Z0-9]+\-?)+[a-zA-Z0-9]+\.)+[a-zA-Z]+$/i','lo-n.l-on.loh-4va.cccccom'));//return 1
echo var_dump(preg_match('/^(([a-zA-Z0-9]+\-?)+[a-zA-Z0-9]+\.)+[a-zA-Z]+$/i','lon.lon.lon.loh4va.cccc5com'));//return false
echo var_dump(preg_match('/^(([a-zA-Z0-9]+\-?)+[a-zA-Z0-9]+\.)+[a-zA-Z]+$/i','lon.lon.lon.loh4va.cccccom'));//return 1</code>
登入後複製
登入後複製

看程式碼你只是過濾。 int(0)代表沒配對到,int(1)是配對成功。

幫你改一下程式碼吧,分組擷取不能亂用,正規書寫要簡潔,還要盡量提高運作效率,還不能儲存無謂的變數。要搞懂正規引擎的回溯原理才能明白自己在幹嘛。

更初級一點的知識,你至少要了解貪婪匹配和非貪婪匹配匹配原理和運作效率的差異。

原:

<code>preg_match('/^(([a-zA-Z0-9]+\-?)+[a-zA-Z0-9]+\.)+[a-zA-Z]+$/i','lo-n.l-on.loh-4va.ccccc5om');</code>
登入後複製

改:

<code>preg_match('/^(?:(?:\w+\.?\w+)-?){4}$/', 'lo-n.l-on.loh-4va.ccccc5om'); </code>
登入後複製

我以題主的問題來分析一下。

以題主的第一段程式碼為例:

<code>preg_match('/^(([a-zA-Z0-9]+\-?)+[a-zA-Z0-9]+\.)+[a-zA-Z]+$/i','lo-n.l-on.loh-4va.ccccc5om')</code>
登入後複製

這段php正規表示式preg_match為什麼有時候會return false?

共花費74781步, 7萬多步!
改成我上面修改後的

<code>preg_match('/^(?:(?:\w+\.?\w+)-?){4}$/', 'lo-n.l-on.loh-4va.ccccc5om');</code>
登入後複製

後:

這段php正規表示式preg_match為什麼有時候會return false?

只需要34步。

分析一下配對過程.
題主的:

這段php正規表示式preg_match為什麼有時候會return false?

修改後的配對步驟:

這段php正規表示式preg_match為什麼有時候會return false?

74781步 : 34 步 約等於2200%, 效率真的是天壤之別.

----補充於dec 29 ---
關於正規的學習:
我是在learning perl裡詳細研究過。個人覺得用好正則主要需要遵循下面幾點:
1 分清什麼時候用貪婪匹配、非貪婪匹配
2 盡量用錨位符
3 能分組的盡量分組
4 元字符與其枚舉不如反向過濾和概括,如,[a-zA-Z0-9]+不如w+,某些特定場景裡,w+不如1+,如果再加上錨位符(b錨字,?= ?>, ?!正反向預搜尋), 那就更快了. 所謂量詞嵌套,就是不該用貪婪匹配(+*的時候就盡量少用,這樣能極大程度上減少backtrack,也就是回溯次數。
更感性的認識,我要找出10億個排成一排裡的人裡男性,你直接告訴我最明顯的一個過幾個特徵就行了,比如那兩棵相距100萬平方公里裡的一排都是男性,沒必要告訴我100個特徵讓我一個一個去核對。

以上。


    -s ↩

http://php.net/manual/zh/func...

preg_match()傳回 pattern 的符合次數。 它的值將是0次(不匹配)或1次,因為preg_match()在第一次匹配後 將會停止搜尋。 preg_match_all()不同於此,它會一直搜尋subject 直到到達結尾。 如果發生錯誤preg_match()回傳 FALSE。

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板