phpの置き換えに付いて教えて下さい。


ここから<a href="">ここまで</a>を<img src="x.gif" alt="ここ画像" />ここのように



<a href="x.html">ここ</a>から<a href="">ここまで</a>を<img src="x.gif" alt="ここ画像" /><a href="x.html">ここ</a>のように

とする置き換えるコードを教えて下さい。

「ここ」をリンクにしたいのですが、aタグの中と、alt属性の値部分は置き換えないようにしたいのです。

よろしくお願いします。

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2012/06/18 20:41:31
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:TransFreeBSD No.2

回答回数668ベストアンサー獲得回数268

ポイント80pt

http://ideone.com/SdAOd
基本は「(<a.*?<\/a>)|(ここ)」と同じですが、ちょっと改良したのと、「<.*?\>」(phpなので念のため>をエスケープしてます)というパターンを追加してます。
「<a.*?<\/a>」は「<(a)\b.*?<\/\3>」とすることで

  • 最初の「a」が単語である(後に英数字が続かない)こと
    • そうでないと<address>タグとかにマッチする(後ろに<a></a>があれば)
  • 閉じタグが前と対応していること

となってます。二つ目は不要かもしれませんが、たとえばコメントアウトしてあるやつのように、「(a)」を「(a|textarea)」とすればaタグ以外にtextareaタグに囲まれている部分も置換しなくなります。
追加したパターンが「<.*?\>」なので

  • imgに限らずすべてのタグ内の「ここ」は置換しません

実用的にはこちらの方だろうと思います。もしimgに限定したいなら「<img\b.*?\>」になります。
あと、修飾子eに加えてiも指定してるので、タグが大文字でも対応します。
#面倒なので<>はすべて<>に変換してます。

<?php
$path = "x.html";
$string = fgets(STDIN);
$patterns = '!(ここ)|(<(a)\b.*?</\3>|<.*?\>)!ie';
//$patterns = '!(ここ)|(<(a|textarea)\b.*?</\3>|<.*?\>)!ie';
$replace = '"\1"?"<a href=\"$path\">\1</a>":"\2"';
echo preg_replace($patterns, $replace, $string);
?>
id:worldtravel

ありがとうございます。
これから試してみます。

2012/06/18 19:54:26
id:worldtravel

上手く行きました!
ありがとうございました。

2012/06/18 20:39:59

その他の回答1件)

id:windofjuly No.1

回答回数2625ベストアンサー獲得回数1149

ポイント20pt

一例

<?php
// データ準備
$t = 'ここから<a href="">ここまで</a>を<img src="x.gif" alt="ここ画像" />ここのように';

// 置換パターン準備
$p = array(
    '!ここ!',
    '!(a.+?)<a href="x.html">ここ</a>!'
);
$r = array(
    '<a href="x.html">ここ</a>',
    '$1ここ'
);
// 置換と出力
echo preg_replace($p, $r, $t);


//下記と同じ意味になっています。
echo preg_replace('!(a.+?)<a href="x.html">ここ</a>!', '$1ここ', preg_replace('!ここ!', '<a href="x.html">ここ</a>', $t ) );

出力結果

<a href="x.html">ここ</a>から<a href="">ここまで</a>を<img src="x.gif" alt="ここ画像" /><a href="x.html">ここ</a>のように
他1件のコメントを見る
id:worldtravel

ありがとうございます。

2012/06/18 19:54:11
id:windofjuly

弱点の箇所については、
alt="ここ画像" があったのでわざと < を省いています。
alt="ここ画像"の記述がないのであれば下記のように < を加えます。

$p = array( '!ここ!', '!(<a.+?)<a href="x.html">ここ</a>!' );

実際のテキストはもっと複雑でしょうから、
自身で修正しやすいように、
簡単な正規表現で出来ることを考慮しています。

コメントすると改行位置で変な文字が混じるので一行に書き直しました。

2012/06/18 20:05:26
id:TransFreeBSD No.2

回答回数668ベストアンサー獲得回数268ここでベストアンサー

ポイント80pt

http://ideone.com/SdAOd
基本は「(<a.*?<\/a>)|(ここ)」と同じですが、ちょっと改良したのと、「<.*?\>」(phpなので念のため>をエスケープしてます)というパターンを追加してます。
「<a.*?<\/a>」は「<(a)\b.*?<\/\3>」とすることで

  • 最初の「a」が単語である(後に英数字が続かない)こと
    • そうでないと<address>タグとかにマッチする(後ろに<a></a>があれば)
  • 閉じタグが前と対応していること

となってます。二つ目は不要かもしれませんが、たとえばコメントアウトしてあるやつのように、「(a)」を「(a|textarea)」とすればaタグ以外にtextareaタグに囲まれている部分も置換しなくなります。
追加したパターンが「<.*?\>」なので

  • imgに限らずすべてのタグ内の「ここ」は置換しません

実用的にはこちらの方だろうと思います。もしimgに限定したいなら「<img\b.*?\>」になります。
あと、修飾子eに加えてiも指定してるので、タグが大文字でも対応します。
#面倒なので<>はすべて<>に変換してます。

<?php
$path = "x.html";
$string = fgets(STDIN);
$patterns = '!(ここ)|(<(a)\b.*?</\3>|<.*?\>)!ie';
//$patterns = '!(ここ)|(<(a|textarea)\b.*?</\3>|<.*?\>)!ie';
$replace = '"\1"?"<a href=\"$path\">\1</a>":"\2"';
echo preg_replace($patterns, $replace, $string);
?>
id:worldtravel

ありがとうございます。
これから試してみます。

2012/06/18 19:54:26
id:worldtravel

上手く行きました!
ありがとうございました。

2012/06/18 20:39:59

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません