こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

正規表現について

HTMLファイルを読み込み、特定の文字列にリンクを付けて出力したいのですが上手くいきません。

例: <img src="./seiki_hyougen.gif" alt="正規表現についての説明">更に正規表現を知りたい方は、<a href="special.html">正規表現の詳しい説明</a>をクリックして下さい。

 ↓正規表現をキーワードにしてリンクを付けたい。

正:<img src="./seiki_hyougen.gif" alt="正規表現についての説明">更に<a href="seiki_hyougen.html">正規表現</a>を知りたい方は、<a href="special.html">正規表現の詳しい説明</a>をクリックして下さい。

誤:<img src="./seiki_hyougen.gif" alt="<a href="seiki_hyougen.html">正規表現</a>についての説明">更に<a href="seiki_hyougen.html">正規表現</a>を知りたい方は、<a href="special.html"><a href="seiki_hyougen.html">正規表現</a>の詳しい説明</a>をクリックして下さい。


尚、下記URLのサンプルを参考にしてスクリプトを作成しています。
http://php.oss.eznetsols.org/manual/ja/function.preg-split.php

$r = preg_split('((\/a>)|(<a))', $html, -1, PREG_SPLIT_DELIM_CAPTURE);
for ($i = 0; $i < count($r); $i++) {
if ($r[$i] == "<a") {
$i++; continue;
}
$r[$i] = preg_replace(
"/(正規表現)/i", "<a href='seiki_hyougen.html'>\\1</a>", $r[$i]
);
}
return join("", $r);

この(正規表現)の部分で上手い正規表現を使えばalt="×××"の中にリンクタグが入らないようにできるのでは?と思っているのですが・・・。

どうか、良い方法を教えて下さい。よろしくお願いいたします。

投稿日時 - 2005-03-05 18:10:29

QNo.1252403

困ってます

質問者が選んだベストアンサー

ごめんなさい。複数のキーワードに対応しようとして
余計なことをしてしまいました。
訂正します。

<?php
$msg = <<<EOF
<img src="./seiki_hyougen.gif" alt="正規表現についての説明">更に正規表現を知りたい方は、<a href="special.html">正規表現の詳しい説明</a>をクリックして下さい。
EOF;

$links = array (
'正規表現' => '<a href="seiki_hyougen.html">正規表現</a>',
);

$link_keys = array_keys($links);
$link_values = array_values($links);

# 表示用関数
function printandreturn ($str) {
print stripslashes("$str");
return "";
}

function printwithlink ($str) {
global $link_keys, $link_values;
print str_replace($link_keys, $link_values, stripslashes($str));
return "";
}

# 処理開始

# 文字化け対策
$msg = str_replace("\\", "\\\\", $msg);

# メインループ
while (strlen($msg)) {
# アンカー部分をスキップ
if (strpos($msg, '<a') === 0) {
$msg = preg_replace("|^(.*?</a>)|e", "printandreturn ('$1')", $msg);
continue;
}
# タグ部分をスキップ
if ($msg[0] == '<') {
$msg = preg_replace("|^(<.*?>)|e", "printandreturn ('$1')", $msg);
continue;
}

# 次のタグまでをリンク付きで表示
foreach ($links as $key => $value) {
$msg = preg_replace("|^([^<]+)|e", "printwithlink ('$1')", $msg);
}
}
?>

投稿日時 - 2005-03-08 16:11:00

お礼

回答ありがとうございます。
複数のキーワードに対応させようと思っていたので下記回答も大変に有用な情報になりました。

いろいろな切り口があるな~と関心して回答を拝見しました。
なかなか回答が得られなかったので、

<?php

$html=<<<EOF
<img src="./seiki_hyougen.gif" alt="正規表現についての説明">更に正規表現を知りたい方は、<a href="special.html">正規表現の詳しい説明</a>をクリックして下さい。
EOF;

$r = preg_split('((\/a>)|(<a))', $html, -1, PREG_SPLIT_DELIM_CAPTURE);
for ($i = 0; $i < count($r); $i++) {
if ($r[$i] == "<a") {
$i++; continue;
}
$r1 = preg_split('(alt=\".*?\")', $r[$i], -1, PREG_SPLIT_DELIM_CAPTURE);
for ($i1 = 0; $i1 < count($r1); $i1++) {
$r1[$i1] = preg_replace(
"/($word1)/i", "<span class='hilite'>\\0</span>", $r1[$i1]
);
}
$r[$i]=join("", $r1);
}
$html=join("", $r);
?>

というようなスクリプトを考えました。
autumnskyさんのスクリプトも参考にしながらよりよい処理にしたいと思います。
ありがとうございました!

投稿日時 - 2005-03-08 18:34:00

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.3

かなり富豪的なので重そうですが…
特に終了条件が危険なので自信ないです。

<?php
$msg = <<<EOF
<img src="./seiki_hyougen.gif" alt="正規表現についての説明">更に正規表現を知りたい方は、<a href="special.html">正規表現の詳しい説明</a>をクリックして下さい。
EOF;

$links = array (
'正規表現' => '<a href="seiki_hyougen.html">正規表現</a>',
);

# 表示用関数
function printandreturn ($str) {
print stripslashes("$str");
return "";
}

function printwithlink ($str, $key, $value) {
print str_replace($key, $value, stripslashes($str));
return "";
}

# 処理開始

# 文字化け対策
$msg = str_replace("\\", "\\\\", $msg);

# メインループ
while (strlen($msg)) {
# アンカー部分をスキップ
if (strpos($msg, '<a') === 0) {
$msg = preg_replace("|^(.*?</a>)|e", "printandreturn ('$1')", $msg);
continue;
}
# タグ部分をスキップ
if ($msg[0] == '<') {
$msg = preg_replace("|^(<.*?>)|e", "printandreturn ('$1')", $msg);
continue;
}

# 次のタグまでをリンク付きで表示
foreach ($links as $key => $value) {
$msg = preg_replace("|^([^<]+)|e", "printwithlink ('$1', '$key', '$value')", $msg);
}
}
?>

投稿日時 - 2005-03-08 15:43:37

こんにちは。

えっと、以下のような感じがおっしゃられている条件にある程度似ているテストにはなると思います。

<?
$beforeMsg = <<<EOF
<img src="./seiki_hyougen.gif" alt="正規表現についての説明">更に正規表現を知りたい方は、<a href="special.html">正規表現の詳しい説明</a>をクリックして下さい。
EOF;

$afterMsg = preg_replace("/[^\">](正規表現)/" , "<a href=\"seiki_hyougen.html\">\\1</a>" , $msg);

print $afterMsg;
?>

ただですね・・・、私の環境
OS:Linux , PHP:ver5 , 文字コード:UTF
OS:Windows , PHP:ver4 , 文字コード:EUC

で、実験したんですけど文字化けを起こしますね・・・。

$afterMsg = stripslashes(preg_replace("/[^\">](正規表現)/" , "<a href=\"seiki_hyougen.html\">\\1</a>" , $msg));

とやってみたり、

ereg_replace('[^">](正規表現)' , "\<a href='seiki_hyougen.html'>\\1</a>" , $msg);

など色々やってみたんですけど、文字化けするようです・・・。

すいません。原因はわかりません・・・。

ただ考え方こんな感じです。正規表現の場合は「文字列」を置換するのではなく「パターンにマッチした文字列」を置換する。と、いった考え方です。

今回は、『「正規表現」という文字列』ではなく、『「"」か「>」が前につかない「正規表現」というパターン』を置換する。

文字コードが「UTF」であれば、パターン修正子に「u」を指定してみてください。
今回は、

"/[^\">](正規表現)/u" ←iだと、大文字小文字区別なくになります。

投稿日時 - 2005-03-06 00:58:16

補足

↓campanella_77さんへの回答に対するお礼に誤りがありました。

<img src="./seiki_hyougen.gif" alt="えーと、<a href=\"seiki_hyougen.html\">正規表現</a>についての説明">
が発生する・・・でした。

投稿日時 - 2005-03-07 16:41:07

お礼

回答ありがとうございます。
しかしながら、お答え頂いたスクリプトだと、

<img src="./seiki_hyougen.gif" alt="<a href=\"seiki_hyougen.html\">正規表現</a>についての説明">

が発生してしまうと思います。

質問させて頂いたスクリプトの「(正規表現)」部分にalt=""内の文字列"正規表現"は一致させないような正規表現を求めています。

ありがとうございました!

投稿日時 - 2005-03-07 09:16:27

ANo.1

その文字列が何個あるのか、何番目に出現するのかは決まってないんですよね?。。。

投稿日時 - 2005-03-05 18:29:15

補足

HTMLファイル中にという事ですよね?
はい。個数、何番目共に決まっていません。

実際に行いたい作業としては、今まで作ってきた数多くのhtmlファイルがあるのですが、どうにか簡単にリンクを張れないものかと思って作成している次第です。

どうぞ、よろしくお願いいたします。

投稿日時 - 2005-03-05 19:20:38

あなたにオススメの質問