以下代码有什么问题 - 我将其精确定位到注释中的连字符,但为什么会导致错误?
import re
valid = re.compile(r'''[^
uFFFEuFFFF # non-characters
]''', re.VERBOSE)
Traceback (most recent call last):
File "valid.py", line 5, in <module>
]''', re.VERBOSE)
File "/usr/local/lib/python3.3/re.py", line 214, in compile
return _compile(pattern, flags)
File "/usr/local/lib/python3.3/re.py", line 281, in _compile
p = sre_compile.compile(pattern, flags)
File "/usr/local/lib/python3.3/sre_compile.py", line 494, in compile
p = sre_parse.parse(p, flags)
File "/usr/local/lib/python3.3/sre_parse.py", line 748, in parse
p = _parse_sub(source, pattern, 0)
File "/usr/local/lib/python3.3/sre_parse.py", line 360, in _parse_sub
itemsappend(_parse(source, state))
File "/usr/local/lib/python3.3/sre_parse.py", line 506, in _parse
raise error("bad character range")
sre_constants.error: bad character range
没有连字符的下一段没有错误:
import re
valid = re.compile(r'''[^
uFFFEuFFFF # non characters !! no errors
]''', re.VERBOSE)
编辑:
除了@nhahtdh的答案之外,字符串连接似乎是以详细样式注释字符类的另一种合理方法:
valid = re.compile( r'[^'
r'u0000-u0008' # C0 block first segment
r'u000Buu000C' # allow TAB U+0009, LF U+000A, and CR U+000D
r'u000E-u001F' # rest of C0
r'u007F' # disallow DEL U+007F
r'u0080-u009F' # All C1 block
r']' # don't forget this!
r'''
| [0-9] # normal verbose style
| [a-z] # another term +++
''', re.VERBOSE)
根据文档(强调我的):
基本上,字符
re.X
re.VERBOSE
此标志允许您编写看起来更好的正则表达式。模式中的空格将被忽略,除非在字符类中或前面有未转义的反斜杠,并且当一行既不在字符类中包含"#",也不在前面包含未转义的反斜杠时,从最左侧的"#"到行尾的所有字符都将被忽略。
类中不能有注释,字符类中的空格被认为是重要的。
由于#
位于字符类内部,因此它不能用作注释,并且字符类中的所有内容都无一例外地解析为字符类的一部分(甚至换行字符也作为字符类的一部分解析)。由于n-c
字符范围无效,因此会引发错误。
编写表达式的有效方法是:
valid = re.compile(r'[^uFFFEuFFFF] # non-characters', re.VERBOSE)
这里有一个关于当你想解释一个冗长的字符类时如何评论的建议:
r'''
# LOTS is for foo
# _ is a special fiz
# OF-LITERAL is for bar
[^LOTS_OF-LITERAL]
'''
正则表达式中并不总是很好,看起来您的正则表达式引擎正在将连字符解析为正则表达式的一部分。您不能依赖此处未解析的注释。在实现此代码之前,最好先了解一下。