Условное регулярное выражение Python - PullRequest
5 голосов
/ 28 июня 2010

Это вопрос, связанный с условным регулярным выражением в python:

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

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

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

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

Следующий код ALMOST делает это, проблема в том, что в первом случае 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)

Ответы [ 3 ]

6 голосов
/ 28 июня 2010

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

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)

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

3 голосов
/ 28 июня 2010

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

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
1 голос
/ 28 июня 2010
myre = '^(?=\s{0,2}(\w)(?:(\w)(\w))?)'

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...