Python Findall, группа и труба - PullRequest
       8

Python Findall, группа и труба

0 голосов
/ 02 августа 2011
x = "type='text'"
re.findall("([A-Za-z])='(.*?)')", x) # this will work like a charm and produce
                                     # ['type', 'text']

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

x = 'type="text"' # see the quotes

По сути, следующее регулярное выражение должно работать, но с findall это приводит к чему-то странному:

([A-Za-z])=('(.*?)')|"(.*?)")

И я не могу использовать ['"] вместо канала, потому что это может привести к плохим результатам:

value="hey there what's up?"

Теперь, как я могу построить такое регулярное выражение, которое будет применяться к одинарным или двойным кавычкам? Кстати, не предлагайте парсеры html или xml, так как я не заинтересован в них.

Ответы [ 2 ]

5 голосов
/ 02 августа 2011

shlex будет лучше работать здесь, но если вы настаиваете на re, используйте ([A-Za-z]+)=(?P<quote>['"])(.+?)(?P=quote)

1 голос
/ 02 августа 2011

Проблема в том, что в ([A-Za-z]+)=('(.*?)'|"(.*?)") у вас есть четыре группы, а вам нужно только две (вероятно, вы нашли странные результаты). Если вы используете ([A-Za-z]+)=('.*?'|".*?"), то все будет в порядке. Помните, что вы можете исключить группировку, поставив (?:), так что это будет эквивалентно: ([A-Za-z]+)=('(?:.*?)')|"(?:.*?)").

РЕДАКТИРОВАТЬ : Я только что понял, что это решение будет включать окружающие кавычки, которые вам не нужны. Вы можете легко снять их, хотя. Вы также можете использовать обратную ссылку, но тогда у вас будет одна дополнительная группа, которую следует удалить в конце, например:

import re
from operator import itemgetter

x = "type='text' TYPE=\"TEXT\""
print map(itemgetter(0,2), re.findall("([A-Za-z]+)=(['\"])(.*?)\\2", x)) 

дает [('type', 'text'), ('TYPE', 'TEXT')].

...