>>> re.match(r'"([^"]|(\\\"))*"', r'"I do not know what \"A\" is"').group(0)
'"I do not know what \\"'
>>> re.match(r'"((\\\")|[^"])*"', r'"I do not know what \"A\" is"').group(0)
'"I do not know what \\"A\\" is"'
这两个正则表达式用于查找带引号的字符串,带有转义引号序列。除非我遗漏了某些东西,否则差异就是括号中分离的顺序。
为什么他们都不接受整个字符串?
答案 0 :(得分:2)
你说的是真的,顺序是不同的。还有别的不一样
第一个"([^"]|(\\\"))*"
将匹配逃生,使其成为
匹配"asdf\"
sde"而另一个则没有。
此外,如果你必须处理转义引用,你也必须处理转义。所以,两者都不是有效的。
以下是两种标准方法。
两者都处理逃脱。
您也可以将其扩展为单引号
如果您想跨越换行符,请使用Dot-All修饰符(?s)
。
方法1. - 交替
"(?:\\.|[^"\\]+)*"
"
(?:
\\ . # Escape anything
| # or,
[^"\\]+ # Not escape not quote
)*
"
方法2. - 展开循环
"[^"\\]*(?:\\.[^"\\]*)*"
"
[^"\\]* # Optional not escape not quote
(?:
\\ . # Escape anything
[^"\\]* # Optional not escape not quote
)*
"
两者都这样做。方法2比方法1快三到五倍。
答案 1 :(得分:1)
交替小组的顺序很重要。
在第一个正则表达式中,首先为每个字符尝试[^"]
替代。它匹配每个单个字符,直至(包括)第一个\
。在下一个字符("
)上,此替代字符([^"]
)失败,另一个字符(\\\"
)尝试。后者也失败,因为"A
与\\\"
不匹配。这会使量词*
停止进一步匹配。
在第二个正则表达式中,\\\"
替代(括号是多余的)首先尝试每个字符并失败,因此第二个替代([^"]
)匹配。但是在第一个\
处,第一个替代匹配,因此查找指针移过\"
到A
并继续查找。
作为一般经验法则,首先将最窄的表达式放在交替中。
答案 2 :(得分:0)
正则表达式r'(A|B)'
将首先尝试匹配A,并且只有在失败后才会尝试匹配B(docs)
因此正则表达式([^"]|(\\\")
将首先尝试匹配非引用,如果失败,它将尝试匹配转义的引号。
因此,当正则表达式达到\"A\"
时,第一部分与\
匹配(它不是引号。但是这两个部分都不匹配"
,所以匹配结束于那里。反斜杠被[^"]
吞噬,因此表达式的后半部分从未使用过。
转到((\\“)| [^”]),当它到达\"A\"
时会首先尝试匹配\"
(它有效)然后它将尝试匹配{{1 (它匹配A
,因此匹配继续。