プロが教える店舗&オフィスのセキュリティ対策術

単語検索のスクリプトで利用者がミスタイプしたときにもマッチするようにしたいと考えています。

例えば、1文字間違って入力した場合にもマッチするように以下のようなスクリプトを書いたのですが、もっと簡単な記述が(標準以外のモジュールを使わずに)できないでしょうか?ご教示いただけましたら嬉しいです。

以下のスクリプトでしていること・・・
hello を .ello|h.llo|he.lo|hel.o|hell. に変換してマッチ。

use strict;

my $data = "hallo";

my $query = "hello";
my $q_len = length $query;
my $query1 = $query;
my @queries;

for (my $i=0;$i<$q_len;$i++){
substr($query1, $i,1,".");
push @queries, $query1;
$query1=$query;
}

my $regex = join ("|", @queries);

if ($data=~/$regex/){
print "matched\n";
}else{
print "no match\n";
}

A 回答 (3件)

>正規表現で .ello|h.llo|he.lo|hel.o|hell. を簡単に記述する方法はありませんでしょうか


#あんまり変わってないけど
use strict;

my $data = "hallo";

my $query = "hello";
my @queries = ($query) x length($query);
my $i=0;
my $regex = join "|" , map { substr($_, $i++, 1, "."); $_ } @queries;
if ($data=~/$regex/){
print "matched\n";
}else{
print "no match\n";
}
    • good
    • 0
この回答へのお礼

ありがとうございます。BLUEPIXYさんのご回答いつも参考になります。map したのをその行の中で join できるんですね~。($query) x length($query) も今まで見たことがありませんでした。

これ、使わせていただこうと思います。

お礼日時:2006/02/25 23:48

音が似ている英単語という事なら、モジュールText::Soundexを使うという手も。


use Text::Soundex;
$data = soundex( 'hello' );

print $data eq soundex( 'hallo' ) ? '' : 'no ', 'matched';

参考URL:http://perldoc.perl.org/Text/Soundex.html
    • good
    • 0
この回答へのお礼

ありがとうございます!面白いモジュールがあるんですね~。勉強になりました。

お礼日時:2006/02/24 09:09

#とりあえず、長さが同じということであれば、


#以下のような感じでどうでしょう?
use strict;

my $data = "hallo";

my $query = "hello";
my $i=0;
my $unmatch=0;

foreach (split(//,$query)){
$unmatch++ if substr($data, $i++,1) ne $_;
}

if ($unmatch<=1){
print "matched\n";
}else{
print "no match\n";
}

この回答への補足

ご回答いただき有難うございます!大変勉強になります。foreach (split(//,$query)) とか if substr($data, $i++,1) ne $_; とか自分の発想の中にはありませんでした。

自分の説明がまったく不足していたのですが、実は $data には1万字以上が入る予定で、$query とその前後百字を取り出したいと思っています。

正規表現で .ello|h.llo|he.lo|hel.o|hell. を簡単に記述する方法はありませんでしょうか。←はなからこう聞けばよかったですね。すみません・・・

?=$query(.) みたいな。
↑まったくのでたらめです・・

補足日時:2006/02/24 09:06
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!