Найти комбинацию вхождеий Х слов в произвольной последовательности

Статус
В этой теме нельзя размещать новые ответы.
Не понял вопроса, приведите пример плиз
Или имеется в виду, что данная регулярка будет реагировать и на такие выражения, как
word1 word1 word1 word1
?
 
Можно повозиться с негативным просмотром вперед, но я думаю что рациональнее будет просто отфильтровать всю выборку на повторение слов
 
По регуляркам рекомендую книжку - Для просмотра ссылки Войди или Зарегистрируйся , есть ответы на все вопросы.

В ней можно узнать, что есть несколько реализаций регулярных выражений, и в данной задаче важно это уточнить, в частности какой механизм и язык используется... явно будет полезно наличие мета-символа \b или \> и \< тоже самое касается и вопросов поддержки юникода, так же это касается и использования | поиска множественных альтернатив - где-то это может быть ужасно не оптимально... в общем первое правило - четко поставить задачу и определить допустимые погрешности результатов.
По задаче, ее мне кажется оптимальней будет решать смесью регулярки и некой постобработки (как пример выше) или вообще логичнее будет написать свой алгоритм который будет работать быстрее и оптимальнее.

ps:
А раз уж ломаете голову над задачей целый год - данная книжка для самообразования будет очень полезна.
 
Пришлось вернуться к этой теме. Появилась похожая задача, решаемая методом
PHP:
~(?:word1\s*|word2\s*|word3\s*|word4\s*){4}~
только вместо word1 и остальных слов идут перечисления слов в разных родах, падежах, спряжениях. Вот пример:
PHP:
/(?:(инфраструктура|инфраструктуры|инфраструктуре|инфраструктуру|инфраструктурой|инфраструктурою|инфраструктур|инфраструктурам|инфраструктурами|инфраструктурах)\s*|
(сесть|сел|села|село|сели|сяду|сядем|сядешь|сядете|сядет|сядут|сев|севши|сядемте|сядь|сядьте|севший|севшего|севшему|севшим|севшем|севшая|севшей|севшую|севшею|севшее|севшие|севших|севшими|селу|селом|селе|селам|селами|селах)\s*|
(и)\s*|
(ее|она|нее|ней|ей|ею|нею)\s*|
(роля|роли|роле|ролю|ролей|ролею|роль|ролям|ролями|ролях|ролью)\s*|
(в)\s*|(развитие|развитье|развития|развитья|развитию|развитью|развитием|развитьем|развитии|развитьи|развитий|развитиям|развитьям|развитиями|развитьями|развитиях|развитьях)\s*|
(сельскохозяйственный|сельскохозяйственного|сельскохозяйственному|сельскохозяйственным|сельскохозяйственном|сельскохозяйственная|сельскохозяйственной|сельскохозяйственную|сельскохозяйственною|сельскохозяйственное|сельскохозяйственные|сельскохозяйственных|сельскохозяйственными|сельскохозяйствен|сельскохозяйственен|сельскохозяйственна|сельскохозяйственно|сельскохозяйственны|сельскохозяйственнее|сельскохозяйственней|посельскохозяйственнее|посельскохозяйственней)\s*|
(производство|производства|производству|производством|производстве|производств|производствам|производствами|производствах)\s*){3,10}/uism
Количество перечислений в каждой группе слов я изначально не знаю, но при формировании паттерна уже знаю. Для приведенного шаблона вылазиет ошибка: Compilation failed: regular expression is too large at offset 19052

Погуглил, на stackoverflow предлагают добавить в код
PHP:
// essential for huge PCREs
ini_set("pcre.backtrack_limit", "230013370");
ini_set("pcre.recursion_limit", "230013370");
// imagine your PCRE here...
Далее идет опровержение данного предложения и другое предложение: разбивать шаблон на мелкие части и как-то далее обрабатывать с помощью алгоритмов php. Второй день сижу думаю: Что за алгоритмы можно применить? И еще вопрос можно ли как-то уменьшить длину паттерна, если известно, что в перечислении идут однородные слова?
 
Последнее редактирование:
Регулярку укоротить можно, но в реале это практически ничего не даст. Лучше изменить алгоритм, например: разбивать текст на слова и искать нужные слова и их последовательность. Не все задачи рационально решать с помощью регулярок.
 
Лучше изменить алгоритм, например: разбивать текст на слова и искать нужные слова и их последовательность. Не все задачи рационально решать с помощью регулярок.
Сейчас первым шагом ищу каждое отдельное слово. Если оно есть в тексте, то включаю в регулярку, если его нету, то исключаю. В результате размер регулярки значительно уменьшился... время выполнения скрипта увеличилось...
 
:) появилась еще более извращенная потребность искать слова. Теперь нужно найти такое:
word1 (от 0 до 4 произвольных любых слов в тексте) word2 (от 0 до 4 произвольных любых слов в тексте) word3
word1, word2, word3 - исходные слова, что и выше. Могут встречаться в произвольном перемешанном варианте. Между ними от 0 до 4 слов с произвольными знаками препинания.
Исходную регулярку модифицировать не удалось.
 
На просторах интернета встретил обсуждение нечто похожего Для просмотра ссылки Войди или Зарегистрируйся
Речь шла про первое вхождение из 20 слов, из которых два слова - однобуквенные.
Там подошло бы что-нибудь простое.
( слово | предлог ){20}

Осталось придумать, как проконтролировать, что бы совпадение с предлог было ровно два раза.
Думаю реализовать через условные подмаски (?(condition)yes-pattern|no-pattern).
Библиотека PCRE допускает использование относительного номера подмаски +2,-3 и т.д.
Код:
( (?(-1) (?!) | pattern ) )
Такая конструкция проверяет, участвовала ли внешняя пара сохраняющих круглых скобок в совпадении и не дает ей совпасть повторно.

Код:
(
  слово
  |
  ( (?(-1) (?!) | предлог ) )
  |
  ( (?(-1) (?!) | предлог ) )
){20}
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху