phpの正規表現について。


phpで、htmlの中のaタグによるリンクURLを取得しようとしていますが、うまくいきません。

例えば、aタグは

<a href="http://....">なんたら</a>
<a href=https:...>なんたら</a>
<a href="/nantara.html">なんたら</a>
<a href="/nantara/">なんたら</a>

など、様々なケースがあります。

この
href=●●の●●の部分のURLを取得して、
別の言葉▲▲を含めたURLに置換したいと思っています。


例えば、

<a href="http://hatena.ne.jp/">はてな</a>



<a href="http://ime.nu/http://hatena.ne.jp/">はてな</a>

のような感じにしたいと思っています。


preg_replaceで正規表現を使っていますが、
なかなか上手く動かないです。

上記を実現のために参考になるURLや、
function形式で参考コードをお願いします。

回答の条件
  • 1人5回まで
  • 登録:2007/07/31 18:35:56
  • 終了:2007/07/31 23:55:56

ベストアンサー

id:GEN111 No.4

GEN111回答回数472ベストアンサー獲得回数582007/07/31 20:04:27

ポイント100pt

質問の意図を正しく解釈してないかもしれませんが。

function append_link($html, $appendix) {
  $html = preg_replace('#(<a\s[^>]*?href\s*=["])(?!http)#i', '$1http://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['REQUEST_URI']), $html) ; // 相対アドレス
  return preg_replace('!(<a\s[^>]*?href\s*=["\']?)!i', "$1$appendix", $html) ;
}

$str = '
<a href="http://www.hatena.ne.jp">はてな</a>
<a href="https://www.yahoo.co.jp">やふー</a>
<a href="/hoge/">ほげ</a>
' ;

echo append_link($str, 'http://ime.nu/') ;
id:onigirin

どうもありがとうございます。

無事変換されました!

正規表現は可能性が無限大ですね。

本当に助かりました!

2007/07/31 23:50:48

その他の回答(3件)

id:Yota No.1

Yota回答回数453ベストアンサー獲得回数282007/07/31 19:02:10

ポイント23pt

function replace_link($str) {

$pattern = '/(<a href=").+(">.+<\/a>)/';

$replacement = '$1http://ime.nu/http://hatena.ne.jp/$2';

return preg_replace($pattern,$replacement,$str) ;

}

id:onigirin

どうもありがとうございます。

試してみたところ、htmlの一番最後にあるリンクだけ変換され、それ以外の文字情報などは全て消えてしまいました・・・。

2007/07/31 19:38:13
id:wizemperor No.2

wizemperor回答回数379ベストアンサー獲得回数522007/07/31 19:10:49

ポイント23pt

関数にするまでもないと思いますが一応しておきます。

function replace_href($html, $pre) {
$pattern = '/(<a(?:\s+?.+?)?\shref=["\'])((?:https?:\/\/|\/?\.+?).*?)(["\'](?:\s?.*?)?>)/';
$replace = '\1' . $pre . '\2\3';

return preg_replace($pattern, $replace, $html);
}

$htmlにHTMLを、$preに付け加えるURLを渡してください。

たとえば次のような感じです。

$html = replace_href('
<a href="http://hatena.ne.jp/">はてな</a>', 'http://ime.nu/');

この場合、$htmlには

<a href="http://ime.nu/http://hatena.ne.jp/">はてな</a>

が入ります。

id:wizemperor No.3

wizemperor回答回数379ベストアンサー獲得回数522007/07/31 19:17:26

ポイント22pt

一部間違えました。

$pattern の部分は

$pattern = '/(<a(?:\s+?.+?)?\shref=["\'])(.*?)(["\'](?:\s?.*?)?>)/';

でよかったですね。

href属性の前後に他の属性が入っている場合や、シングルクォーテーションでもダブルクォーテーションでも対応できます。

id:onigirin

どうもありがとうございます。

おおよそ無事変換されましたが、

htmlコード内にリンクが複数ある場合、

「変換される」「変換されない」「変換される」・・・と、リンクが1つおきに変換されてしまいました・・・。

2007/07/31 19:40:39
id:GEN111 No.4

GEN111回答回数472ベストアンサー獲得回数582007/07/31 20:04:27ここでベストアンサー

ポイント100pt

質問の意図を正しく解釈してないかもしれませんが。

function append_link($html, $appendix) {
  $html = preg_replace('#(<a\s[^>]*?href\s*=["])(?!http)#i', '$1http://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['REQUEST_URI']), $html) ; // 相対アドレス
  return preg_replace('!(<a\s[^>]*?href\s*=["\']?)!i', "$1$appendix", $html) ;
}

$str = '
<a href="http://www.hatena.ne.jp">はてな</a>
<a href="https://www.yahoo.co.jp">やふー</a>
<a href="/hoge/">ほげ</a>
' ;

echo append_link($str, 'http://ime.nu/') ;
id:onigirin

どうもありがとうございます。

無事変換されました!

正規表現は可能性が無限大ですね。

本当に助かりました!

2007/07/31 23:50:48
  • id:kn1967
    wizemperorさんのような方法が良いとは思いますけど
    タグの部分は無視して単純に
    $b = preg_replace("/(href=\")([^\"]+)(\")"/", "$1追加$2$3" ,$a);
    としてしまうほうが楽で確実かもしれませんよ。
  • id:wizemperor
    >「変換される」「変換されない」「変換される」・・・と、リンクが1つおきに変換されてしまいました・・・。

    複数ある場合はもうちょと変えないとだめですね。(フラグも抜けてた)
    ということはHTMLをそのまま置換したいという感じだと思うので、
    hrefからマッチさせようとした場合も、HTML中の普通のテキストまで変換されてしまうのでだめですね。

    たぶん、GEN111さんのやりかたでうまくいくのではないかと思いますが。
  • id:onigirin
    どうもありがとうございます。

    GEN111さんのコードでなんとか目的を達成することができました。


    それぞれ書いて頂いたコードも、
    それを使うと実現できなかった部分と、
    実現できた部分を見比べることで、理解が進みました。

    どうもありがとうございました。
  • id:GEN111
    最初の preg_replace の ["] は ["\'] に訂正しておきます。
    相対アドレスは ../hoge/ みたいな形だとダメダメですね……
  • id:onigirin
    どうもありがとうございます。
    修正しておきますね。

    実は相対アドレスなのですが、
    「自スクリプトのURL」とは別のURLのhtmlを
    変換しています。

    例えば、http://www.hatena.ne.jp/を取得して、
    リンク先を「ime.nu/」を付加した変換をする感じです。

    そのため、相対アドレスのところは
    GEN111さんのままではできなかったのですが、
    一つ解決したのでとても助かりました。


    たぶん、この点も正規表現でなんとかなりそうな気がするので、
    またこれから戦う予定です・・・。
    なんとなく流れはわかるのですが、
    正規表現をうまく書けないのが悔しいです・・・。
  • id:Yota
    function replace_link($str) {
    $pattern = '/(<a href=")[^>]+(">[^<]+<\/a>)/';
    $replacement = '$1http://ime.nu/http://hatena.ne.jp/$2';
    preg_match_all($pattern,$str,$matches) ;
    // print_r($matches[0]) ;
    for($i = 0 ;$i < count($matches[0]) ;$i++ ) {
    $matches_r[] = preg_replace($pattern,$replacement,$matches[0][$i]) ;
    }
    return str_replace($matches[0],$matches_r,$str) ;
    }
  • id:onigirin
    どうもありがとうございます。

    自分のプログラムへの組み込み方が悪かったのか、
    うまく変換できなかったです・・・。

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

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

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

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