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回まで
  • 13歳以上
  • 登録:2012/06/18 17:56:53
  • 終了:2012/06/18 20:41:31

ベストアンサー

id:TransFreeBSD No.2

TransFreeBSD回答回数665ベストアンサー獲得回数2672012/06/18 19:27:37

ポイント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ベストアンサー獲得回数11492012/06/18 18:37:46

ポイント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

TransFreeBSD回答回数665ベストアンサー獲得回数2672012/06/18 19:27:37ここでベストアンサー

ポイント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

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

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

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

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

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません