Я работаю над довольно специализированной реализацией поисковой системы в Perl, это ищет (regex) документы для конкретно разграниченного (подмножество: punct:) представляет в виде строки от текстового файла. Я делаю обычные приемы индексирования в поисковых системах, но существует проблема.
Часть поиска regex шаблоны включает, при необходимости, разделители, используемые в файле. "Хорошо, я думаю мне, "близость слова, затем... легкая"... и та сторона уравнения, является достаточно прямой.
Прием - то, что, потому что шаблоны поиска являются регулярными выражениями, я легко не определил определенные слова, которые я должен пойти, ища в индексируемых данных (думайте "разделение", если мы говорим о более обычных строках).
Тривиальный пример, "квадрат [\s-]*dance" соответствовал бы непосредственно на "squaredance", но соответствие близости на "кадрили" и "кадрили" (так как '-' является разделителем). Я должен знать, на основе regex, чтобы искать "квадрат" и "танцевать" отдельно, но поблизости друг друга.
Я - игра для проблемы, но я использовал бы установленный код. Мой пищеварительный тракт говорит мне, что это будет внутренний рычаг к regex механизму, но я не знаю ни о чем как этот. Какие-либо предложения?
Прагма 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)