2016-08-03 1 views
3

Вот регулярное выражение у меня до сих пор:Регулярное выражение для сопоставления нескольких POSTIVE LOOKAHEAD группы

^(?=.*(option1|option2))(?=.*(option3|option4))(?=.*(option5|option6))(?=.*(option7|option8))(?=.*(option9|option10)).*$ 

Я не хип на языке регулярных выражений, так что я буду делать свои собственные определения:

категории 1 (опция1 | вариант2), категория 2 - (опция 3 | вариант4), категория 3 - (опция5 | опция6) и т. д.

Я хотел бы получить значения, где по крайней мере 1 вариант из 3 или более категорий найдено, например:

некоторый текст OPTION3 еще какой-нибудь текст option8 еще какой-нибудь текст option1

ИЛИ

некоторый текст OPTION3 еще какой-нибудь текст option8 еще какой-нибудь текст option1 некоторые больше текста option6

Я не хотите, чтобы захватить значения, как это:

некоторый текст OPTION3 еще какой-нибудь текст option8 - только 2 категории представлены

ИЛИ

некоторые текст OPTION3 еще какой-нибудь текст ОПЦИЯ4 некоторые более текст option1 (варианты 3 и 4 относятся к той же категории)

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

Что касается движка регулярных выражений, я должен использовать интерфейс интерфейса, который работает под управлением python в фоновом режиме. Я могу использовать только регулярное выражение, у меня нет возможности использовать любые другие функции python. Благодаря!

ответ

1

Вот regex, который делает то, что вы хотите (в режиме VERBOSE):

^ 
(?= .* (?: option1 | option2) ())? 
(?= .* (?: option3 | option4) ())? 
(?= .* (?: option5 | option6) ())? 
(?= .* (?: option7 | option8) ())? 
(?= .* (?: option9 | option10)())? 
.*$ 
(?: \1\2\3 | \1\2\4 | \1\2\5 | \1\3\4 | \1\3\5 | 
    \1\4\5 | \2\3\4 | \2\3\5 | \2\4\5 | \3\4\5) 

Пустые группы служат в качестве флажков: если закрывающий просмотр не удался, обратная ссылка на эту группу не удастся. Неконвертирующая группа в конце содержит все возможные комбинации из трех из пяти обратных ссылок.

Ограничения этого подхода очевидны; вам нужно добавить еще один набор option s, чтобы он полностью вышел из-под контроля. Я думаю, вам будет лучше с решением без регулярных выражений.

+0

Благодарим за это решение! Можете ли вы объяснить немного больше, что такое режим VERBOSE? Интерфейс интерфейса пользователя, который я должен использовать, не позволяет перейти в режим VERBOSE. Может ли это быть записано в режиме по умолчанию для python (не уверен, что это называется)? –

+0

Вы можете указать режим VERBOSE в самом регулярном выражении, добавив '(? X)' в начало. Или вы можете удалить все пробелы из регулярного выражения: '^ (? =. * (?: option1 | option2)())? (? =. * (?: option3 | option4)())? (? =. * (?: option5 | option6)()) (= * (?: option7 | option8?.)()) (= * (?: option9 | option10?.)()) * $ (??.? \ 1 \ 2 \ 3 | \ 1 \ 2 \ 4 | \ 1 \ 2 \ 5 | \ 1 \ 3 \ 4 | \ 1 \ 3 \ 5 | \ 1 \ 4 \ 5 | \ 2 \ 3 \ 4 | \ 2 \ 3 \ 5 | \ 2 \ 4 \ 5 | \ 3 \ 4 \ 5) ' –

+0

отлично! Спасибо большое! –

1

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

Вместо этого вы можете хранить свои параметры в наборе, как:

options = {(option1, option2), (option3, option4), (option5, option6), (option7, option8), (option9, option10)} 

Затем проверьте членство, как следующее:

if sum(i in my_text or j in my_text for i, j in options) >= 3: 
    # do something 

Вот демо:

>>> s1 = "some text option8 some more text option3 some more text option1" 
>>> s2 = "some text option3 some more text option4 some more text option1" 
>>> s3 = "some text option3 some more text option8" 
>>> 
>>> options = {('option1', 'option2'), ('option3', 'option4'), ('option5', 'option6'), ('option7', 'option8'), ('option9', 'option10')} 
>>> 
>>> sum(i in s1 or j in s1 for i, j in options) 
3 
>>> sum(i in s2 or j in s2 for i, j in options) 
2 
>>> sum(i in s3 or j in s3 for i, j in options) 
2 
Смежные вопросы