人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

php:正規表現(preg_replace)を使って、HTMLタグの中以外の単語を別のタグに置き換える処理を教えてください。
今、正規表現を使って、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が出てしまいました。

●質問者: S1100
●カテゴリ:コンピュータ ウェブ制作
✍キーワード:echo HTML PHP tag Word
○ 状態 :終了
└ 回答数 : 5/5件

▽最新の回答へ

1 ● pahoo
●20ポイント

preg系でマルチバイト処理を行うのに不安を感じているものですから、mb_ereg系で書いてみました。正規表現だけで対処しきれなかったので、こんなスクリプトににしてみました。

置換前文字列が $str、置換語文字列が $outstr です。

いちおう複数行対応しています。

$pat1 = "(.*)単語([^>]*<)|(>[^<]*)単語(.*)";
$rep1 = "\\1<タグ>\\2";

while (TRUE) {
 $outstr = mb_ereg_replace($pat1, $rep1, $str);
 if ($outstr == $str)break;
 $str = $outstr;
}
◎質問者からの返答

2つ、問題がありました。

?私の環境(PHP5.2.6, UTF8)ではタグ内外ともリプレースされてしまいました。

$str = 'その他の文章など<img src="test.gif" alt="xx単語xx" />xx単語xx';

ちなみにwhileを使わないで一回きりで試してみるとうまくいっています。

?$str = 'その他の文章などxx単語xx';

のように元々にタグがない場合も置換して欲しいです。

すみませんが、調整お願いできますでしょうか。


2 ● GoldenDawn
●20ポイント
<?php
$str = 'その他の文章など<img src="test.gif" alt="xx単語xx" />xx単語xx';

$target = '単語' ;
$dist = '<タグ>' ;
echo preg_replace("/(<.*?>)|($target)/e", "'$1' ? '$1' : '$dist';", $str) ;
?>
◎質問者からの返答

一つ問題がありまして、これをこのまま実行すると

alt=\"のようにダブルクォーテーションの前に"\"がついてしまいました。

調整可能でしょうか。


3 ● GoldenDawn
●20ポイント
<?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 ;
?>
◎質問者からの返答

とりあえずやりたいことはできました。ありがとうございました。


4 ● tezcello
●20ポイント

考え方を変えて、全ての置換をしておいて、タグ内についてはもう一度元に戻すように置換するのは?

$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

の様にエラーになってしまいます。

私にもう少し正規表現のテクニックがあれば簡単なことなのかもしれませんが、すぐには解決できないので、フォローいただけるとありがたいです。


5 ● tezcello
●20ポイント

コメント欄が開いていないのでこちらへ。


正規表現中に、デリミタと同じ文字があると失敗します。(今回の場合は/)

他にも正規表現の特殊文字が出て来ると検索に失敗する可能性が出て来ます。

これらをエスケープするのに 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単語xx単語x単語x';

のように単語が2回以上出てくると、alt属性の2つめ以降は置換されてしまいます。

対処策あれば……

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ