2012-02-18 2 views
2

Это продолжение по сравнению с that question. Я узнал, что поиск совпадающих совпадений регулярных выражений в Python не является прямым, поэтому решил сделать дополнительный запрос, чтобы увидеть, как Perl и Ruby поддерживают эту задачу.Количество совпадений совпадений совпадений в Perl OR Ruby

Я хочу, чтобы подсчет количество всех возможных совпадений регулярного выражения относительно определенной строки. И под «все» я подразумеваю, что в результате должны учитываться как совпадающие, так и неповторимые совпадения. Вот некоторые примеры:

  • a.*k должны быть согласованы дважды в "akka"
  • "bbboob" испытанного против b.*o.*b должен дать 6

В качестве ссылки, вот Perl один вкладыш предложил tchrist - он выводит правильные совпадения и их число:

() = "bbboobb" =~ /(b.*o.*b)(?{push @all, $1})(*FAIL)/g; printf "got %d matches: %s\n", scalar(@all), "@all"; 

Единственный проблема заключается в том, что он потребляет слишком много ресурсов для тестовых случаев, где итоговое количество совпадений составляет порядка миллионов или более. Но я понимаю, что это связано с тем, что все матчи сначала сгруппированы и только потом учитываются. Я ищу ресурсосберегающее решение, которое возвращает только счет.

+0

Если у вас есть регулярное выражение в том смысле, компьютерные науки, это может легко сделать с помощью NFA в O (RN), где R и N - длины регулярного выражения и входных строк). – Nabb

+0

@Nabb Но если вы не используете RE2 (который вы действительно можете использовать в Perl), вы не получите NFA. У вас есть рекурсивный backtracker. См. Документы Русса Кокса. – tchrist

ответ

6

Похоже, tchrist выполнил всю тяжелую работу. При хранении спички и подсчета их потом ест слишком много ресурсов, то вы могли бы просто изменить регулярное выражение встраиваемый код просто сосчитать матчи:

my $count = 0; 

"bbboobb" =~ /(b.*o.*b)(?{$count++})(*FAIL)/g; 

print "got $count matches\n"; 
+0

Возможно, группа, не участвующая в съемке, также может немного ускорить процесс. Либо '(?: B. * O. * B)', либо флаг '/ n', где поддерживается. – Eily

Смежные вопросы