HTML中のhrefの値を一括変換するコードを探しています。


例えば、以下のHTMLを http://input.example.com/menu/ から取得したと仮定して、

<a href="sitemap.html">サイトマップ</a> <!--相対パス-->
<a href="../index.html">トップ</a> <!--相対パス-->
<a href="/help.html">ヘルプ</a> <!--絶対パス-->
<a href="http://www.google.co.jp/">Google</a> <!--外部リンク-->

以下のように変換することができるコードです。

<a href="http://contentproxy.example.com/mobile/http://input.example.com/menu/sitemap.html">
<a href="http://contentproxy.example.com/mobile/http://input.example.com/index.html">
<a href="http://contentproxy.example.com/mobile/http://input.example.com/help.html">
<a href="http://contentproxy.example.com/mobile/http://www.google.co.jp">

コードは Perl, Ruby, PHP, JavaScript のいずれかでお願いします。
ライブラリでも結構です。

回答の条件
  • 1人2回まで
  • 登録:2006/04/14 12:02:17
  • 終了:2006/04/14 14:41:44

回答(1件)

id:bonlife No.1

回答回数421ベストアンサー獲得回数752006/04/14 14:07:24

ポイント60pt

ためしにPHPで書いてみました。

(ご要望とずれていたら申し訳ありません。)

取り込むHTMLファイルはsample.htmlとしています。

適当な名前のPHPファイルにして、sample.htmlと同じディレクトリに保存して実行してみてください。

<?php
// HTMLファイルの読み込み
$lines = file('./sample.html');
// カレントディレクトリのパスを取得
//$dirname = "http://input.example.com/menu/";
$dirname = realpath('.');
// ホスト名の取得
preg_match("/^(http:\/\/)?([^\/]+)/i",$dirname,$matches);
$host = $matches[2];
// ドメイン名の取得
preg_match("/[^\.\/]+\.[^\.\/]+$/", $host, $matches);
$domain = $matches[0];
// 置換処理
for ($i=0;$i<count($lines);$i++){
	// 相対パスの場合の処理
	if (preg_match('/<!--相対パス-->/',$lines[$i])){
		$lines[$i] = preg_replace('/<a href="/',"<a href=\"http://contentproxy." . $domain . '/mobile/' . $dirname, $lines[$i]);
		$lines[$i] = preg_replace('/<\/a>.*<!.*>/','</a>',$lines[$i]);
		print $lines[$i];
	// 絶対パスの場合の処理
	} else if (preg_match('/<!--絶対パス-->/',$lines[$i])){
		$lines[$i] = preg_replace('/<a href="/',"<a href=\"http://contentproxy." . $domain . '/mobile/http://' . $host, $lines[$i]);
		$lines[$i] = preg_replace('/<\/a>.*<!.*>/','</a>',$lines[$i]);
		print $lines[$i];
	// 外部リンクの場合の処理
	} else if (preg_match('/<!--外部リンク-->/',$lines[$i])){
		$lines[$i] = preg_replace('/<a href="/',"<a href=\"http://contentproxy." . $domain . '/mobile/', $lines[$i]);
		$lines[$i] = preg_replace('/<\/a>.*<!.*>/','</a>',$lines[$i]);
		print $lines[$i];
	} else {
		print $lines[$i];
	}
}
?>

ベタ書きしている部分(http://contentproxy)は変数にした方がソースが短くなって良いかもしれないです。

また、2番目の例のような行を置換した場合、

<a href="http://contentproxy.example.com/mobile/http://input.example.com/index.html">

ではなく

<a href="http://contentproxy.example.com/mobile/http://input.example.com/menu/../index.html">

のようになりますが、たいていのブラウザでは適切に解釈されるので問題ないはずです。

一度確認してみてください。

参考になると幸いです。

id:akiyan

>たいていのブラウザでは適切に解釈される

なるほど!たしかにそうですね。

参考になりました。ありがとうございました。

2006/04/14 14:37:33
  • id:mkonomi
    コードというより、テキストエディタの全置換機能で可能です。

    置換前テキスト:
    href="

    置換後テキスト:
    href="http://contentproxy.example.com/mobile/http://input.example.com/menu/

    《秀丸エディタでの操作例》
    置換後テキストをCtrl+Cでクリップボードに入れて、
    置換前テキストをマウスでなぞって反転表示にして、
    Ctrl+R
    置換枠の中へCtrl+V
    必要なら、「置換の前に確認」にチェックを入れて、
    全置換ボタンを押す。

    いつも、この手で変換しています。
  • id:n_koji72
    機械的な置換だと
    1行目の例しかうまくいかないのでは...
  • id:mkonomi
    いつも、この手で変換しています。

    『全置換』なのですべての対象の置換です。
    「置換の前に確認」にチェックを入れないと、一気にすべての対象の置換を行います。

    「置換の前に確認」にチェックを入れると、1件ごとに置換するかパスするかを選択できます。途中から残りを一気に置換することもできます。
    以上はあくまでも『秀丸エディタ』での例です。

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

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

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

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