我正在研究Perl中一个相当专业的搜索引擎实现,它搜索(通过正则表达式)文档,以便从文本文件中特别分隔(一部分:punct :)字符串。我正在做通常的搜索引擎索引技巧,但是有一个问题。
某些搜索正则表达式模式必然包含文件中使用的分隔符。 “好吧,我想对自己说,”接近,然后......很容易“......等式的那一边很直接。
诀窍在于,因为搜索模式是正则表达式,所以我不容易确定我应该在索引数据中寻找的特定单词(如果我们讨论的是更普通的字符串,请考虑“拆分”)。
琐碎的例子,“square [\ s - ] * dance”将直接匹配“squaredance”,但是“square dance”和“square-dance”上的邻近匹配(因为' - '是分隔符)。我需要知道,基于正则表达式,分别寻找“方形”和“舞蹈”,但彼此相邻。
我是挑战的游戏,但我宁愿使用已建立的代码。我的直觉告诉我它将是正则表达式引擎的内部钩子,但我不知道这样的事情。有什么建议吗?
答案 0 :(得分:4)
re
编译指示可以生成您似乎感兴趣的信息。
use strict;
use warnings;
use re qw(Debug DUMP);
my $re = qr/square[\s-]*dance/;
'Let\'s go to the square dance!' =~ $re;
输出:
Compiling REx "square[\s-]*dance"
Final program:
1: EXACT <square> (4)
4: STAR (17)
5: ANYOF[\11\12\14\15 \-][+utf8::IsSpacePerl] (0)
17: EXACT <dance> (20)
20: END (0)
anchored "square" at 0 floating "dance" at 6..2147483647 (checking anchored) minlen 11
Freeing REx: "square[\s-]*dance"
不幸的是,似乎没有一个程序化的钩子来获取这些信息。你必须拦截STDERR上的输出并解析它。粗略的概念验证:
sub build_regexp {
my $string = shift;
my $dump;
# save off STDERR and redirect to scalar
open my $stderr, '>&', STDERR or die "Can't dup STDERR";
close STDERR;
open STDERR, '>', \$dump or die;
# Compile regexp, capturing DUMP output in $dump
my $re = do {
use re qw(Debug DUMP);
qr/$string/;
};
# Restore STDERR
close STDERR;
open STDERR, '>&', $stderr or die "Can't restore STDERR";
# Parse DUMP output
my @atoms = grep { /EXACT/ } split("\n", $dump);
return $re, @atoms;
}
以这种方式使用:
my ($re, @atoms) = build_regexp('square[\s-]*dance');
$re
包含模式,@atoms
包含模式的文字部分列表。在这种情况下,那是
1: EXACT <square> (4)
17: EXACT <dance> (20)