這段代碼有一個錯誤,我找不到它。我需要什麼缺失的角色?正則表達式錯誤php
preg_replace(/<(?!\/?(?:'.implode('|',$white).'))[^\s>]+(?:\s(?:(["''])(?:\\\1|[^\1])*?\1|[^>])*)?>/','',$html);
這段代碼有一個錯誤,我找不到它。我需要什麼缺失的角色?正則表達式錯誤php
preg_replace(/<(?!\/?(?:'.implode('|',$white).'))[^\s>]+(?:\s(?:(["''])(?:\\\1|[^\1])*?\1|[^>])*)?>/','',$html);
它看起來像在其他的東西,你就錯過了一個單引號:
preg_replace('/<(?!\/?(?:' . implode('|',$white) . '))[...
^
here!
此外,由於模式包含單引號,這些也必須由前導反斜槓進行轉義。
或者,您也可以使用heredoc syntax;這將不需要在模式中引用任何轉義,並且表達式可以嵌入到擴展中。
$pattern = <<<EOD
/pattern{embeddedExpression}morePattern/
EOD;
... preg_replace($pattern, ...)
請你幫個忙,並使用DOM and XPath代替正則表達式來解析HTML到avoid problems。
我遵循這個從PHP書 – proyb2 2010-07-18 03:35:20
@ proyb2你應該得到一本新書。這是不好的建議。 – quantumSoup 2010-07-18 03:54:43
那麼,這部分是錯誤的:
(["'])(?:\\\1|[^\1])*?\1
這應該匹配包圍在單或雙引號,可能包括反斜槓轉義引號的序列。但它不起作用,因爲反向引用在字符類中不起作用。 \1
以八進制表示法處理爲數字1
,因此[^\1]
與除U+0001以外的任何字符匹配。
如果它似乎大部分時間工作,這是因爲不情願的量詞(*?
)。 (?:\\\1|[^\1])*?
中的第一個替代方法正確地使用了一個轉義引用,但否則它只是不情願地匹配任何字符,直到它看到一個未轉義的引用。它在格式正確的文本上可以正常工作,但可以在額外的報價中折騰並且無法使用。
匹配「除了捕獲的組#1以外的任何內容」的正確方法是(?:(?!\1).)*
- 即一次只消費一個字符,但僅在該預見確認它不是捕獲的文本的第一個字符之後。但我認爲你會更好地分開處理每種報價。這個正則表達式很複雜。
'~<(?!/?+(?:'.implode('|',$white).')\b)[^\s>]++(?:\s++'.
'(?:[^\'">]++|"(?:[^"\\]++|\\")*+"|\'(?:[^\'\\]++|\\\')*+\')*+)?+>~'
通知白名單中交替後加入\b
(字邊界)的。否則,如果您的列表中包含(例如)<B>
,則會無意中將<BODY>
和<BLOCKQUOTE>
標籤列入白名單。
我也用佔有慾量詞(*+
,++
,?+
)無處不在,因爲這正則表達式的書寫方式,我知道回溯永遠是有用的。如果它失敗了,我希望它儘快失敗。
現在我已經告訴過你如何讓正則表達式工作了,讓我強烈要求你不要使用它。這項工作太複雜,太重要,不適合像正則表達式這樣不適合的工具。如果你真的從一本關於PHP安全的書中得到了這個正則表達式,我建議你把錢還給你。
你有什麼錯誤,什麼是不正確的結果,最重要的是你想達到什麼? – HoLyVieR 2010-07-17 20:50:46
他正試圖解析HTML使用PHP!抓住他! – 2010-07-17 21:21:46
正如下面的Aircule所提到的,我建議你考慮不使用正則表達式來解析HTML。這只是要求麻煩和痛苦。 – 2010-07-18 00:48:49