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解析器,因为我对它们不感兴趣。
答案 0 :(得分:5)
shlex
会在这里做得更好,但如果你坚持re
,请使用([A-Za-z]+)=(?P<quote>['"])(.+?)(?P=quote)
答案 1 :(得分:1)
问题是,在([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')]
。