Это - вопрос, вовлекающий условное регулярное выражение в 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),
Может быть ...:
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
... но Я просто предполагаю, что вам не нужны совпадения в таких случаях ...?)
Каждая группа захвата в выражении получает свой собственный индекс. Попробуйте так:
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
myre = '^(?=\s{0,2}(\w)(?:(\w)(\w))?)'
Это позволит справиться с двумя случаями, которые вы описываете, так, как вы хотите, но не обязательно является общим решением. Такое чувство, что вы придумали проблему с помощью той, которая представляет собой реальную.
Общее решение очень трудно прийти, потому что обработка более поздних элементов зависит от обработки предыдущих и/или обратного. Например, начальные пробелы не должны быть там, если у вас есть полный abc
. И если начальные пробелы есть, вы должны найти только a
.
На мой взгляд, лучший способ справиться с этим — с |
конструкция, которую вы имели изначально. После матча у вас может быть код, который вытаскивает группы в массив и упорядочивает их по своему вкусу.
Правило для групп заключается в том, что все открытые скобки, за которыми не следует сразу ?:
, становятся группой. Эта группа может быть пустой, так как она на самом деле ничего не соответствовала, но она будет там.