Условное регулярное выражение Python

Это - вопрос, вовлекающий условное регулярное выражение в Python:

Я хотел бы соответствовать строке "abc" с

match(1)="a"
match(2)="b"
match(3)="c"

но также и соответствуйте строке " a" с

match(1)="a"
match(2)=""
match(3)=""

Следующий код ПОЧТИ делает это, проблема - это в первом случае match(1)="a" но во втором случае, match(4)="a" (нет match(1) как желаемый).

На самом деле, если Вы выполняете итерации через все группы с for g in re.search(myre,teststring2).groups():, Вы получаете 6 групп (не 3, как ожидался).

import re
import sys

teststring1 = "abc"
teststring2 = "  a"

myre = '^(?=(\w)(\w)(\w))|(?=\s{2}(\w)()())'

if re.search(myre,teststring1):
    print re.search(myre,teststring1).group(1)

if re.search(myre,teststring2):
   print re.search(myre,teststring2).group(1)

Какие-либо мысли? (обратите внимание, что это для Python 2.5),

5
задан Mike 28 June 2010 в 05:24
поделиться

3 ответа

Может быть ...:

import re
import sys

teststring1 = "abc"
teststring2 = "  a"

myre = '^\s{0,2}(\w)(\w?)(\w?)$'

if re.search(myre,teststring1):
    print re.search(myre,teststring1).group(1)

if re.search(myre,teststring2):
   print re.search(myre,teststring2).group(1)

Это дает в обоих случаях, как вы хотите, но, возможно, он не будет соответствовать так, как вы хотите, в других случаях вы не отображаются (например, без пробелов впереди или пробелов и после более чем одной буквы, так что общая длина совпадающей строки составляет ! = 3 ... но Я просто предполагаю, что вам не нужны совпадения в таких случаях ...?)

7
ответ дан 13 December 2019 в 19:21
поделиться

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

r = re.compile("^\s*(\w)(\w)?(\w)?$")

abc -> ('a', 'b', 'c')
a -> ('a', None, None)

Для разбивки:

^     // anchored at the beginning
\s*   // Any number of spaces to start with
(\w)  // capture the first letter, which is required
(\w)? // capture the second letter, which is optional
(\w)? // capture the third letter, which is optional
$     // anchored at the end
3
ответ дан 13 December 2019 в 19:21
поделиться
myre = '^(?=\s{0,2}(\w)(?:(\w)(\w))?)'

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

Общее решение очень трудно прийти, потому что обработка более поздних элементов зависит от обработки предыдущих и/или обратного. Например, начальные пробелы не должны быть там, если у вас есть полный abc. И если начальные пробелы есть, вы должны найти только a.

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

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

1
ответ дан 13 December 2019 в 19:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: