正規表現の単語境界\bは便利ですが、これでうまく行かない場合もあります。
However when we have punctuation characters at the beginning or end of the keyword we add to the TRIE itself, like "#android", this \b gets in the way, since '#' is not a word character.
要するに、こういう場合に困ったぞということです。
#!/usr/bin/perl use strict; use warnings; use Regexp::Trie; my $rt = Regexp::Trie->new; $rt->add($_) for qw( #mac #win #unix ); my $re = $rt->regexp; warn $re; my $text = "I'm watching #mac, #win and #unix."; my @m = $text =~ /\b($re)\b/g; printf "\@m = (%s)\n", join ', ', map { qq('$_') } @m;
しかしこれも、 lookaround assertion (先後読み) が使えるのであれば解決できます。
- 文字境界開始
(?<![chars])(?=[chars])- 文字境界終了
(?<=[chars])(?![chars])
#!/usr/bin/perl
use strict;
use warnings;
use Regexp::Trie;
my $rt = Regexp::Trie->new;
$rt->add($_) for map {'#'.$_} qw( mac win unix );
my $re = $rt->regexp;
warn $re;
my $b = qr/(?<![\w#])(?=[\w#])/;
my $text = "I'm watching #mac, #win and #unix.";
my @m = $text =~ /$b($re)\b/g;
printf "\@m = (%s)\n", join ', ', map { qq('$_') } @m;
以上はPerlの例ですが、先後読み対応の正規表現エンジン搭載の言語であればいずれもいけるはず。
詳しくはフクロウ本のP.130あたりを参照のこと。
Dan the Regular Expressionist

このブログにコメントするにはログインが必要です。
さんログアウト
この記事には許可ユーザしかコメントができません。