2015-12-07 2 views
5

У меня есть предложение, как этотRegexp ленивый квантор

a something* q b c w 

и я должен соответствовать с и д вместе, как

(id_1: a, id_2: q) 

б только как

(id_1: b) 

и с и ж вместе, как (ID_1: с ID_2: ш).

Я пытался использовать это регулярное выражение

(?:\b(?P<id_1>a|b|c)\b(?:.*?)(?P<id_2>q|w)?\b) 

Из-за ленивого оператора *? регулярное выражение соответствует только первая часть предложения, соответствующие только

(id_1: a, id_1: b, id_1: c) 

Live Example

Если мы используем жадный оператор такой, что выражение становится

(?:\b(?P<id_1>a|b|c)\b(?:.*)(?P<id_2>q|w)?\b) 

Live Example

It совпадения

(id_1: a) 

все после соответствует . *.

Если вторая часть является обязательным (с ленивым на *.):

(?:\b(?P<id_1>a|b|c)\b(?:.*?)(?P<id_2>q|w)\b) 

Live Example

он соответствует предложения как

(id_1: a, id_2: q);(id_1: b, id_2: w) 

, как и ожидалось.

Можно использовать регулярное выражение, которое «предпочитает» соответствовать всему предложению (включая дополнительную часть) или соответствует только первой части ТОЛЬКО, если отсутствует дополнительный.

EDIT: Извините, что предоставленные регулярные выражения имели некоторые ошибки.

Последнее регулярное выражение:

(?:\b(?P<id_1>a|b|c)\b(?:.*?)(?P<id_2>q|w)\b) 

и требует как группа является обязательным. Он соответствует «что-то» w, но он не соответствует «чему-то» или просто «а».Мне нужно, чтобы соответствовать «а что-то * W», а также «а» и «ай» и получить соответствующую группу соответственно:

(id_1: a , id_2: w) ; (id_1: a, id_2: none) ; (id_1:a , id_2: w) 

Я думаю, что регулярное выражение требуется:

(?:\b(?P<id_1>a|b|c)\b(?:.*?)(?P<id_2>q|w)?\b) 

но в предложении «что-то * w» оно просто соответствует «a» (из-за ленивого оператора. *).

Я также обновил все живые примеры.

+1

Не ваши последние согласования регулярных выражений строки так, как вам нужно? Я удалил 'b c w', и есть совпадение. Не могли бы вы использовать 1 пример, чтобы описать, что вам нужно в нем, и какое регулярное выражение является самым близким, чего не хватает? –

+0

Привет @stribizhev, спасибо за вашу помощь. Я отредактировал вопрос, потому что в выражениях были некоторые ошибки. Я также привел пример в разделе EDIT. – Desh901

+0

Как ['\ b (? P a | b | c) \ b (?: (?! \ B (?: Q | w) \ b).) * (? P q | w |) \ b '] (https://regex101.com/r/vU4wZ0/4)? Или, возможно, ['\ b (? P a | b | c) \ b (?: (?! \ B (?: Q | w) \ b).) * (? P q | w)? \ b'] (https://regex101.com/r/iP2pZ5/1)? –

ответ

1

Ложное совпадение точек является основной причиной проблемы, так как для этого требуется наличие конечной границы.

Если вам нужно сопоставить текст, который не является конкретным текстом, вы можете использовать 2 вещи: либо умеренный жадный токен, либо регулярное выражение unroll-the-loop.

Если у вас есть переменные, которые вы можете использовать tempered greedy token и сделать вторую группу захвата дополнительно с ? квантора:

\b(?P<id_1>a|b|c)\b(?:(?!\b(?:a|b|c|q|w)\b).)*(?P<id_2>q|w)?\b 
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^   ^

См regex demo

+0

Если у вас есть многострочный вход, не забудьте использовать флаг 're.DOTALL' /' re.S', чтобы '.' мог соответствовать новой строке. –

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