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

Tru*_*ood 8 regex perl search-engine

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

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

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

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

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

Mic*_*man 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;
Run Code Online (Sandbox Code Playgroud)

输出:

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"
Run Code Online (Sandbox Code Playgroud)

不幸的是,似乎没有一个程序化的挂钩来获取此信息。您必须拦截 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;
}
Run Code Online (Sandbox Code Playgroud)

这样使用它:

my ($re, @atoms) = build_regexp('square[\s-]*dance');
Run Code Online (Sandbox Code Playgroud)

$re包含模式,@atoms包含模式的文字部分的列表。在这种情况下,那就是

   1: EXACT <square> (4)
  17: EXACT <dance> (20)
Run Code Online (Sandbox Code Playgroud)