2017-09-12 19 views
0

preg_match_allとpreg_replaceは同じパターンに基づいて同じ一致を見つけられません。preg_match_allは、同じパターンを使用するpreg_replaceとは異なる結果セットを持っています

私のパターンは次のとおりです。

/<(title|h1|h2|h3|h4|h5|ul|ol|p|figure|caption|span)(.*?)><\/(\1)>/ 

私はpreg_match_allで

<span class="blue"></span> 

の同類を含むスニペットに対してこれを実行すると、私は17試合を取得します。

私はpreg_replaceで同じパターンを使用すると、私は0個のマッチを得ます。 \ 1を選択リストに置き換えると一致が見つかりますが、もちろん終了タグが同じタイプの開始タグであることを保証しないため、解決策としては機能しません。

全体的な目標は、コンテンツなしで存在してはならないコンテンツのないタグのインスタンスを見つけることです...聖なる十字軍、私はあなたを保証します。

正規表現が動作するかどうかをテストする際に、私もphp cliで試しました。ここでは、出力は次のようになります。

Interactive shell 

php > $str = 'abc<span class="blue"></span>def'; 
php > $pattern = "/<(title|h1|h2|h3|h4|h5|ul|ol|p|figure|caption|span)(.*?)><\/(\1)>/"; 
php > $final = preg_replace($pattern, '', $str); 
php > print $final; 
abc<span class="blue"></span>def 
+0

(。*?)は常に問題を引き起こすようです。それを以下のように変更してください:([^>] +)少なくとも1より大きくないことを意味します。それがうまくいくなら私に知らせてください、そして私はより完全な答えを書くでしょう。 – sniperd

+0

私が正しく理解していれば、パターンを "/ <($ search)([^>] +)><\/(\1)>/i"に変更したため、preg_match_allに一致しませんでした。タグ名以外に何かが必要であることに気付きましたが、必ずしもそうである必要はありません。ちょうどなので、 "/ <($ search)([^>] *)><\/(\1)>/i "でも一致するものはありません。 – Ayen

+1

ZA̡͊͠͝LGΌ、H̸̡̪̯ͨ͊̽̅̾Ȩ̶̧̨̬̩̹̭̯̾͛ͪ̈ͧ̾ͬ͘C̷̙̝͖ͭ̏ͥͮ͟Oͮ͏̮̪̝͍M̖͊̒ͪͩͬ̚̚͜Ȇ̴̟̟͙̞ͩ͌͝S̨̥̫͎̭ͯ̿̔https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags –

答えて

1
$str = 'abc<span class="blue"></span>def'; 
$pattern = "/<(title|h1|h2|h3|h4|h5|ul|ol|p|figure|caption|span)(.*?)><\/(\\1)>/"; 
                   // added \^
$final = preg_replace($pattern, '', $str); 
print $final; 
// echos 'abcdef' 

説明:最初はエスケープシーケンスであるため、

"\1" // <-- character in octal notation 

'\1' // <-- backslash and 1 

とは非常に異なっています。これはほとんどの場合、一重引用符で囲まれた文字列を排他的に使用する理由です。 http://php.net/string#language.types.string.syntax.double

+0

これは機能します!あなたの変更が1をエスケープするのではなく、バックスラッシュをエスケープすることを正しく読んでいますか? – Ayen

+0

追加の説明 – Jakumi

+0

php -a: 'echo '\ 1';'と '' echo "\ 1"; ' – Jakumi