• ベストアンサー

マッチングの方法

文字列のマッチングについての質問なのですが、 たとえばですが、 変数1:あいうえおかきくけこ 変数2:あいうえおかきんんこ とあった場合、どれだけマッチしているかを考える方法は 10文字中8文字一致なので80%マッチ とか 先頭から7文字は同じであとは違うから70%マッチ とかを考えています。 質問は、 これ以外の判定方法でよいものはあるでしょうか? 上記2つの場合、やはり1文字1文字比較していくしかないでしょうか? perl関数など一通り調べてみたのですが、見つかりませんでした。 おねがいします。

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

  • ベストアンサー
回答No.4

#! /usr/bin/perl use CGI; $q = new CGI; require "jcode.pl"; $a = $q->param('a'); $b = $q->param('b'); $a_tmp = $a; $b_tmp = $b; jcode::convert(\$a_tmp,'euc'); $a_euc = $a_tmp; jcode::convert(\$b_tmp,'euc'); $b_euc = $b_tmp; $ascii = '[\x00-\x7F]'; $twoBytes = '[\x8E\xA1-\xFE][\xA1-\xFE]'; $threeBytes = '\x8F[\xA1-\xFE][\xA1-\xFE]'; @a_chars = $a_euc =~ /$ascii|$twoBytes|$threeBytes/og; @b_chars = $b_euc =~ /$ascii|$twoBytes|$threeBytes/og; $a_cnt = @a_chars; $b_cnt = @b_chars; if($a_cnt > $b_cnt){ $cnt = $a_cnt; }elsif($a_cnt < $b_cnt){ $cnt = $b_cnt; }elsif($a_cnt == $b_cnt){ $cnt = $a_cnt; } $m_cnt=0; for($i=0;$i<=$cnt-1;$i++){ if($a_chars[$i] eq $b_chars[$i]){ $m_cnt++; } } print "Content-type: text/html\n\n"; print "$a:文字数は$a_cnt<BR>\n"; print "$b:文字数は$b_cnt<BR>\n"; print "マッチは$cnt中$m_cnt回です。<BR>\n"; $ans = $m_cnt / $cnt * 100; print "比率は$ans%です"; substrではうまくいかなかったので ネットで調べながら自前で作ってみました。 かなり見苦しいソースになってしまいましたが CGIとして動作するようになっていますから 入力フォームを作ってください。

investyou
質問者

お礼

作成までしていただきありがとうございます。 今解読しながらテストしています。 コードの扱いなど勉強になります。

investyou
質問者

補足

希望どおりの処理ロジックができました! 他マッチングパターンを足していきます。 ありがとうございました!

その他の回答 (3)

回答No.3

自力で処理を作るなら substrで一文字づつそれぞれの変数から 文字を切り出してマッチするかループで 回しながら処理するのはどうでしょうか? あと日本語処理を用いるなら文字コードはEUC で扱った方がいいと思います。 Perlでの日本語処理を調べてみましょう。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

#1を投稿してから何か変だなと思って use encoding 'shiftjis'; を指定した場合で試してみたら 31% で マッチでした。 日本語文字列のマッチングをする場合は、 やはりエンコード指定をする必要があるようです。

investyou
質問者

お礼

回答ありがとうございます。 やりたいことはまさにこれ!なのですが、半角でないと%が狂うようです。 他も探してみます。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

標準モジュールではありませんが、 String::Approx というモジュールがあります。 cpan または、 ppm でインストールできます。 下記のサンプルでは、デフォルトの10%以内の変動だったらマッチするが、5%を指定するとマッチしないということがわかります。 ---------------------------------------------------------------- use String::Approx qw(amatch); if(amatch("あいうえおかきくけこ", "あいうえおかきんんこ")){ print "(10%)match!\n"; } if(amatch("あいうえおかきくけこ", ["5%" ], "あいうえおかきんんこ")){ print "(5%)match!"; }