0
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 解析器,因为我对它们不感兴趣。

4

2 回答 2

5

shlex在这里会做得更好,但如果你坚持re,请使用([A-Za-z]+)=(?P<quote>['"])(.+?)(?P=quote)

于 2011-08-01T22:02:34.043 回答
1

问题是,([A-Za-z]+)=('(.*?)'|"(.*?)")你有四个组,你只需要两个(这可能是你发现结果奇怪的地方)。如果你用([A-Za-z]+)=('.*?'|".*?")那么应该没问题。请记住,您可以通过 put 排除分组(?:),所以这将是等效的:([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')].

于 2011-08-01T22:05:28.487 回答