Как я могу определить “маркеры” (неправильное слово) регулярного выражения

Я работаю над довольно специализированной реализацией поисковой системы в Perl, это ищет (regex) документы для конкретно разграниченного (подмножество: punct:) представляет в виде строки от текстового файла. Я делаю обычные приемы индексирования в поисковых системах, но существует проблема.

Часть поиска regex шаблоны включает, при необходимости, разделители, используемые в файле. "Хорошо, я думаю мне, "близость слова, затем... легкая"... и та сторона уравнения, является достаточно прямой.

Прием - то, что, потому что шаблоны поиска являются регулярными выражениями, я легко не определил определенные слова, которые я должен пойти, ища в индексируемых данных (думайте "разделение", если мы говорим о более обычных строках).

Тривиальный пример, "квадрат [\s-]*dance" соответствовал бы непосредственно на "squaredance", но соответствие близости на "кадрили" и "кадрили" (так как '-' является разделителем). Я должен знать, на основе regex, чтобы искать "квадрат" и "танцевать" отдельно, но поблизости друг друга.

Я - игра для проблемы, но я использовал бы установленный код. Мой пищеварительный тракт говорит мне, что это будет внутренний рычаг к regex механизму, но я не знаю ни о чем как этот. Какие-либо предложения?

8
задан Trueblood 10 May 2010 в 18:23
поделиться

1 ответ

Прагма 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)
4
ответ дан 6 December 2019 в 00:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: