入力テキストに辞書の語が含まれているかどうか正規表現でチェック
2012-01-25-1
[Programming]
入力テキストに辞書の語が含まれているかどうか調べるタスク。
入力テキストの文字位置をずらしながら、各位置で正規表現による「辞書引き」を行い漏れなく調べる方針。
■サンプルコード(regexdic.pl):
■辞書(aiueo.dic):スペース連続はタブ。
■実行例:
ちゃんとした実装にはほど遠いが、急ぎのときのコピペ用に。
文字列長ごとに正規表現を分けているのは、辞書に「あいう」「あい」がある場合に、入力テキスト「あいうえお」で両方にマッチさせるため。事前処理で「あいう」に「あい」が含まれるという情報を持たせて longest のみ得るという方式なら分けなくてもよいがちょっと面倒。なお、longest のみを得る場合は下記のようなパターンを作れば良い。
入力文字列を一文字ずつずらしながらマッチさせているのは、辞書に「あいう」「いうえ」がある場合に、入力テキスト「あいうえお」で両方にマッチさせるため。
ref.
- [を] 正規表現でCommon Prefix Search [2007-05-15-1]
- [を] SUFARY.pm で Longest Common Prefix Search[2007-05-15-5]
入力テキストの文字位置をずらしながら、各位置で正規表現による「辞書引き」を行い漏れなく調べる方針。
■サンプルコード(regexdic.pl):
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use open ':utf8';
binmode STDIN, ":utf8";
binmode STDOUT, ":utf8";
my $dic_fn = shift @ARGV;
my %token;
open(my $fh, "<:utf8", $dic_fn) or die;
while (<$fh>) {
chomp;
next if /^\s*$/;
my ($k, $c) = split(/\t/, $_, 2);
$token{length($k)}{$k} = $c;
}
close($fh);
my %pat;
foreach my $i (keys %token) {
$pat{$i} = join("|", keys %{$token{$i}});
}
while (<>) {
print "> $_";
chomp;
next if /^\s*$/;
my $s_ref = get_matched_strings(\%pat, $_);
print join("\n", map {"$_\t".$token{length($_)}{$_}} sort keys %$s_ref)."\n";
}
sub get_matched_strings {
my ($pat_ref, $text) = @_;
my %match;
for (my $i = 0; $i < length($text); $i++) {
foreach my $len (keys %{$pat_ref}) {
$match{$1}++ if $text =~ /^.{$i}($pat_ref->{$len})/;
}
}
return \%match;
};
■辞書(aiueo.dic):スペース連続はタブ。
あいう r:aiu あい r:ai,k:愛 いえ r:ie,k:家 いうえ r:iue うあい r:uai えあ r:ea おい r:oi,k:甥
■実行例:
% echo 'あいうえおい' | ./regexdic.pl aiueo.dic > あいうえおい あい r:ai,k:愛 あいう r:aiu いうえ r:iue おい r:oi,k:甥
ちゃんとした実装にはほど遠いが、急ぎのときのコピペ用に。
文字列長ごとに正規表現を分けているのは、辞書に「あいう」「あい」がある場合に、入力テキスト「あいうえお」で両方にマッチさせるため。事前処理で「あいう」に「あい」が含まれるという情報を持たせて longest のみ得るという方式なら分けなくてもよいがちょっと面倒。なお、longest のみを得る場合は下記のようなパターンを作れば良い。
$pat_all = join("|", sort {length($b) <=> length($a)} keys %token_all);
入力文字列を一文字ずつずらしながらマッチさせているのは、辞書に「あいう」「いうえ」がある場合に、入力テキスト「あいうえお」で両方にマッチさせるため。
ref.
- [を] 正規表現でCommon Prefix Search [2007-05-15-1]
- [を] SUFARY.pm で Longest Common Prefix Search[2007-05-15-5]
