今、正規表現を使って、HTML文章中の単語を、別のタグに置き換える処理をPHPにて実装しています。
が、この方法がわかりません。
最初は単純に単語をタグに置き換えると、タグ中に入っていた単語も別のタグに置き換えられてしまいます。
例えば
<img src="xxx" alt="xx単語xx">単語
が
<img src="xxx" alt="xx<タグ>xx"><タグ>
になってしまいます。
例)
本当は
<img src="xxx" alt="xx単語xx">単語
を
<img src="xxx" alt="xx単語xx"><タグ>
としたいです。
時間がないため質問させていただきます。
http://q.hatena.ne.jp/1174034774
をみて見よう見まねでやってみたのですが
$html = 'その他の文章など<img src="test.gif" alt="xx単語xx" />xx単語xx';
$word = '単語';
$tag = '<タグ>';
echo preg_replace('/(<("[^"]*"|\'[^\']*\'|[^>])*>'.$word.'?)|'.$word.'/e', '"$1"?str_replace("\\\'","\'","$1"):'.$tag, $html);
Failed evaluating codeが出てしまいました。
preg系でマルチバイト処理を行うのに不安を感じているものですから、mb_ereg系で書いてみました。正規表現だけで対処しきれなかったので、こんなスクリプトににしてみました。
置換前文字列が $str、置換語文字列が $outstr です。
いちおう複数行対応しています。
$pat1 = "(.*)単語([^>]*<)|(>[^<]*)単語(.*)"; $rep1 = "\\1<タグ>\\2"; while (TRUE) { $outstr = mb_ereg_replace($pat1, $rep1, $str); if ($outstr == $str) break; $str = $outstr; }
<?php $str = 'その他の文章など<img src="test.gif" alt="xx単語xx" />xx単語xx'; $target = '単語' ; $dist = '<タグ>' ; echo preg_replace("/(<.*?>)|($target)/e", "'$1' ? '$1' : '$dist';", $str) ; ?>
一つ問題がありまして、これをこのまま実行すると
alt=\"のようにダブルクォーテーションの前に"\"がついてしまいました。
調整可能でしょうか。
<?php $str = 'その他の文章など<img src="test.gif" alt="xx単語xx\" />xx単語xx'; $target = '単語' ; $dist = '<タグ>' ; $out = preg_replace("/(<.*?>)|($target)/e", "'$1' ? '$1' : '$dist';", $str) ; $out = str_replace('\"', '"', $out) ; echo $out ; ?>
とりあえずやりたいことはできました。ありがとうございました。
考え方を変えて、全ての置換をしておいて、タグ内についてはもう一度元に戻すように置換するのは?
$html = 'その他の文章など<img src="test.img" alt="xx単語xx" />xx単語xx'; $word = '単語'; $tag = '<タグ>'; $replaced = preg_replace("/$word/u", "$tag", $html); $replaced = preg_replace("/(<[^>]+?)$tag([^>]+?>)/u", "$1$word$2", $replaced);
場合によってはうまくいくのですが
$tagの中にsrc="/img/soccer.gif"のような、スラッシュのついた属性の時
Warning: preg_replace() [function.preg-replace]: Unknown modifier 'g' in
の様にエラーになってしまいます。
私にもう少し正規表現のテクニックがあれば簡単なことなのかもしれませんが、すぐには解決できないので、フォローいただけるとありがたいです。
コメント欄が開いていないのでこちらへ。
正規表現中に、デリミタと同じ文字があると失敗します。(今回の場合は/)
他にも正規表現の特殊文字が出て来ると検索に失敗する可能性が出て来ます。
これらをエスケープするのに preg_quote() という関数が使えると思います。
こんな感じでどうでしょう?
http://jp.php.net/manual/ja/function.preg-quote.php
$html = 'その他の文章など<img src="test.img" alt="xx単語xx" />xx単語xx'; $word = '単語'; $tag = '<タグ>'; $replaced = preg_replace('/'.preg_quote($word, '/').'/u', $tag, $html); $replaced = preg_replace('/(<[^>]+?)'.preg_quote($tag, '/').'([^>]+?>)/u', "$1$word$2", $replaced);
回答数制限ですので、必要ならコメントを開けておいて下さい。
ありがとうございます。
ほぼやりたいことができましたが。
$html = 'その他の文章などx単語x単語x';
のように単語が2回以上出てくると、alt属性の2つめ以降は置換されてしまいます。
対処策あれば……
2つ、問題がありました。
①私の環境(PHP5.2.6, UTF8)ではタグ内外ともリプレースされてしまいました。
$str = 'その他の文章など<img src="test.gif" alt="xx単語xx" />xx単語xx';
ちなみにwhileを使わないで一回きりで試してみるとうまくいっています。
②$str = 'その他の文章などxx単語xx';
のように元々にタグがない場合も置換して欲しいです。
すみませんが、調整お願いできますでしょうか。