如何识别正则表达式的“标记”(错误的单词)

时间:2010-05-10 18:23:58

标签: regex perl search-engine

我正在研究Perl中一个相当专业的搜索引擎实现,它搜索(通过正则表达式)文档,以便从文本文件中特别分隔(一部分:punct :)字符串。我正在做通常的搜索引擎索引技巧,但是有一个问题。

某些搜索正则表达式模式必然包含文件中使用的分隔符。 “好吧,我想对自己说,”接近,然后......很容易“......等式的那一边很直接。

诀窍在于,因为搜索模式是正则表达式,所以我不容易确定我应该在索引数据中寻找的特定单词(如果我们讨论的是更普通的字符串,请考虑“拆分”)。

琐碎的例子,“square [\ s - ] * dance”将直接匹配“squaredance”,但是“square dance”和“square-dance”上的邻近匹配(因为' - '是分隔符)。我需要知道,基于正则表达式,分别寻找“方形”和“舞蹈”,但彼此相邻。

我是挑战的游戏,但我宁愿使用已建立的代码。我的直觉告诉我它将是正则表达式引擎的内部钩子,但我不知道这样的事情。有什么建议吗?

1 个答案:

答案 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)