Perlにて、以下のようなソースがあります。


foreach $i (keys %RLIST){
if($i ne ''){
$str =~ s/\G((?:[\x00-\x7F]|[\x8E\xA1-\xFE][\xA1-\xFE]|\x8F[\xA1-\xFE]{2})*?)\Q$i\E/$1<a href="$RLIST{$i}" $style>$i<\/a>/g;
}
}
これは、ハッシュのキーワードをHTML文中に見つけたらハッシュに定義されているリンクを設定するものです。
例としてハッシュに(AB,XXX),(ABC,YYY)があるものとします。
このままだと、本文中にABCがあるとき、ABがひっとしてしまいます。そこでハッシュを逆順にして(reverse)みたのですが、今度は<a href="YYY"><a href="XXX">AB</a>C</a>という間抜けなものになってしまいました。
この場合は<a href="YYY">ABC</a>となってほしいのですが、置き換え部分を弄ってそのように出来るのであれば知りたいです。(正規表現はさっぱり駄目なので解説はしていただいても理解できません)
よろしくお願いします。

回答の条件
  • 1人3回まで
  • 登録:
  • 終了:2007/05/22 00:22:33
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答5件)

id:irukajp No.1

回答回数174ベストアンサー獲得回数2

ポイント20pt

http://www.kent-web.com/perl/chap7.html

上記はダミー

$str =~ s/\b((?:[\x00-\x7F]|[\x8E\xA1-\xFE][\xA1-\xFE]|\x8F[\xA1 -\xFE]{2})*?)$i\b/$1

id:metatron3rd

書いてなかったのですが、HTML文中にはキーワードが複数回登場します。

また、お教えいただいた方法ではリンクされたりされなかったりします。あるキーワードは複数回リンクされるけどあるキーワードは1回だけリンクされるというような動作をします。また、ABCはリンクされましたがABは無視されてしまいました(1回もリンクされません)判りにくくてすいません・・・

2007/05/21 16:19:50
id:GEN111 No.2

回答回数472ベストアンサー獲得回数58

ポイント20pt
foreach $i (sort {$b cmp $a} (keys %RLIST)) {
  if($i ne ''){
    $str =~ s/\G((?:[\x00-\x7F]|[\x8E\xA1-\xFE][\xA1-\xFE]|\x8F[\xA1-\xFE]{2})*?)\Q$i\E/$1<a href="$RLIST{$i}" $style>$i<\/a>/g ;
    $str =~ m!<a.+?>.*?</a>!g ;
  }
}

これではどうでしょう。

ただし、ここに来る前に $str にリンクがあるとダメですが。

id:metatron3rd

回答ありがとうございます。

試してみたのですが、以下のような状態となりました。

・ABはリンクされず、ABCはリンクされる。

・他にもDEFやGHIなどのキーワードがありますが、((DEF,XYZ)、(GHI,ZZZ)として)GHIへのリンクのされ方がGHIのようになってしまいました。GHIへリンクされない場合もあります。

・リンクされないものがほとんどとなりました。

2007/05/21 22:26:04
id:b-wind No.3

回答回数3344ベストアンサー獲得回数440

ポイント20pt

正規表現ダメと言いつつ、変わったコード書いてますねえ。

my $regex = '(' . join ( '|', sort { $b cmp $a } keys %RLIST ) . ')';
s!$regex!<a href="$RLIST{$i}" $style>$i</a>!g;

こういうことではないの?

id:metatron3rd

私が書いたわけではなく、公開されているスクリプトを見て、置き換え処理部分はここだろうなと思って質問したのです。

なお、うまくいきませんでした。

一つ上と同じ症状なので、私がうまくソースを置き換えで来ていないのかも知れませんが・・・

2007/05/21 23:45:51
id:GEN111 No.4

回答回数472ベストアンサー獲得回数58

ポイント20pt

すいません。

foreach $i (sort {$b cmp $a} (keys %RLIST)) {
  if($i ne ''){
    $str =~ s!(<a.+?>.*?</a>)|(\Q$i\E)!$1?$1:qq{<a href="$RLIST{$i}" $style>$i</a>}!e ;
  }
}

これではどうでしょうか。

id:metatron3rd

>すいません。

いえいえ、とんでもないです。

試してみましたが症状は同じでした。一つ上でもコメントしたのですが、私がソース修正をミスしているのかもしれませんのでもう少し確認してみます。

2007/05/21 23:45:53
id:b-wind No.5

回答回数3344ベストアンサー獲得回数440

ポイント20pt
my $regex = '(' . join ( '|', sort { $b cmp $a } keys %RLIST ) . ')';
$str =~ s!$regex!<a href="$RLIST{\1}" $style>\1</a>!g;

ちょっとミスがあったので。たぶん結果は同じだろうけど。


なお、うまくいきませんでした。

何がどううまくいかないのかこっちではさっぱり分からないので、もうちょっと実例を出して説明してくれると進むんじゃないかな。

id:metatron3rd

確かに。

当初考えていたのは「そのものずばりの答え」か「そんなことは不可能です」のどちらかかなぁと思ってたので、該当部分だけ抜き出して質問すればいいかと思ってました。

質問の仕方が悪いのでせっかく教えてもらっても実行結果の症状もうまく伝えられなくなってます。

一旦閉じて、具体例とどこのソースかを提示させていただいて、もう一度質問させていただきます。

2007/05/22 00:19:45
  • id:lunlumo
     こうですかね。

    >||
    foreach my $i (sort { length($b) <=> length($a) } keys(%RLIST)){
    if($i ne ''){
    $str =~ s/\G((?:(?:[\x00-\x7F]|[\x8E\xA1-\xFE][\xA1-\xFE]|\x8F[\xA1-\xFE]{2})(?:<a.*?>.*?<\/a>)?)*?)\Q$i\E/$1<a href=\"$RLIST{$i}\">$i<\/a>/g;
    }
    }
    ||<

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

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

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

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