【问题标题】:Python RegEx missing parenthesis errorPython RegEx 缺少括号错误
【发布时间】:2016-12-09 04:37:00
【问题描述】:

我正在访问一些旧的 python 代码,以前没有抛出任何错误,但是当我尝试运行它时遇到了错误。这是给我一个错误的代码:

import re

text = r"I quote \"How're you?\" to you."
double = [z.start() for z in re.finditer('(?<!\\)(?:\\\\)*(")', text)]
single = [z.start() for z in re.finditer("(?<!\\)(?:\\\\)*(')", text)]
print(double)
print(single)

我希望从这个程序中得到的输出是:

[]
[13]

然而,这给了我错误:

double = [z.start() for z in re.finditer('(?<!(?:\\))(?:\\\\)*(")', text)]
File "C:\Users\Me\AppData\Local\Programs\Python\Python35-32\lib\re.py", line 220, in finditer
return _compile(pattern, flags).finditer(string)
File "C:\Users\Me\AppData\Local\Programs\Python\Python35-32\lib\re.py", line 293, in _compile
p = sre_compile.compile(pattern, flags)
File "C:\Users\Me\AppData\Local\Programs\Python\Python35-32\lib\sre_compile.py", line 536, in compile
p = sre_parse.parse(p, flags)
File "C:\Users\Me\AppData\Local\Programs\Python\Python35-32\lib\sre_parse.py", line 829, in parse
p = _parse_sub(source, pattern, 0)
File "C:\Users\Me\AppData\Local\Programs\Python\Python35-32\lib\sre_parse.py", line 437, in _parse_sub
itemsappend(_parse(source, state))
File "C:\Users\Me\AppData\Local\Programs\Python\Python35-32\lib\sre_parse.py", line 722, in _parse
source.tell() - start)
sre_constants.error: missing ), unterminated subpattern at position 0

值得一提的是我在运行这个之前已经更新了python,那么可能是python的更新导致了这个错误? (我现在正在运行python 3.5.2,但是我不记得之前是什么了)

另外,如果有帮助,我试图找到所有没有被反斜杠转义的单引号或双引号,即

' 和 " 被拾取

\' 和 \" 不是

\' 和 \" 被拾取等等...

我打算使用它来将字符串中的嵌套字符串与字符串的其他部分分开。

这是导致问题的负面后视 (?

奇怪的是,这适用于regex101,所以我开始没有办法调试它了。

我尝试了不同的替代方法来替代负面的后视,以试图让它发挥作用:

(?<!\) #Gets the error, but that is expected

(?<!\\\\) #Same error again, same problem as the original case

(?<!\\\) #Returns [8, 20] and [13]

很明显,最后一个语法不正确。然而,Python 将其解释为正确,但我不知道它实际上将其解释为什么。

无论如何,我知道可能有一些简单的解释,也许是一些我不知道的 RegEx 语法。

另外,如果我正在尝试的方法有一个替代的、不那么混乱的解决方案,请随时给我那个解决方案。

非常感谢,我的头发都快掉光了,

EdW

【问题讨论】:

  • regex101 自动将其设为原始字符串 r'...'。可以试试吗?

标签: python python-3.5


【解决方案1】:

只需将r 添加到正则表达式字符串的前面

import re
text = r"I quote \"How're you?\" to you."
double = [z.start() for z in re.finditer(r'(?<!\\)(?:\\\\)*(")', text)]
single = [z.start() for z in re.finditer(r"(?<!\\)(?:\\\\)*(')", text)]
print(double)
print(single)

输出:

[]
[13]

【讨论】:

  • 要清楚,这样做的原因是它禁用了字符串文字的反斜杠的转义行为,除非后面的字符是用于开始字符串的引号字符。当你不这样做时,你传递给finditer 的内容包含文字字符(?&lt;!\)(?:\\)*(");然后它将第一个 \ 解释为转义(出于正则表达式的目的)紧随其后的括号。 总是对正则表达式使用原始字符串; Python 是“有用的”,只处理定义的转义('\d' 是 len 2;'\\' 是 len 1),但是当您不期望转义处理时,它只会让人更加困惑。
  • 哇...这比我想象的要简单得多。至少我做得“正确”,只是python试图“有帮助”。感谢 Navidad 的回复,并感谢 ShadowRanger 的解释。
  • @EdW:嗯,Python 在这里做的很正确。问题是它在 other 场景中做错了事情,例如允许\d\s 等被解释为后跟一个字母的反斜杠(因此它们到达正则表达式引擎并被正确解释),而\b\\ 和其他一些则为 ASCII转义和正则表达式转义都被解释为它们的转义值。 Python 将 \\ 转换为 \ 是正确的,只是它应该转换 more 反斜杠转义符,以便人们始终如一地遇到这个问题,而不是在遇到异常之前一切正常。
猜你喜欢
  • 2015-03-31
  • 1970-01-01
  • 2016-10-23
  • 1970-01-01
  • 2016-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多