详细的正则表达式注释中的连字符会导致错误

时间:2013-09-17 04:37:03

标签: python regex

以下代码有什么问题 - 我在评论中将其指向连字符,但为什么会导致错误?

import re

valid = re.compile(r'''[^
\uFFFE\uFFFF   # 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'''[^
\uFFFE\uFFFF   # non characters !! no errors
]''', re.VERBOSE)

修改

添加@nhahtdh的答案,字符串连接似乎是另一种以详细样式注释字符类的合理方法:

valid = re.compile( r'[^'
r'\u0000-\u0008'    # C0 block first segment
r'\u000Bu\u000C'    # 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)

2 个答案:

答案 0 :(得分:7)

根据文件(强调我的):

  

re.X
  re.VERBOSE

     

此标志允许您编写看起来更好的正则表达式。 模式中的空格被忽略,除非在字符类中或前面有未转义的反斜杠,并且当一行不包含字符类中的'#'或前面没有未转义的反斜杠时,最左边的所有字符这一行中的'#'将被忽略。

基本上,你不能在字符类中进行注释,并且字符类中的空格被认为是重要的。

由于#在字符类中,因此它不作为注释运行,并且字符类中的所有内容都被解析为字符类的一部分而没有异常(即使新行字符被解析为字符的一部分类)。由于n-c是无效的字符范围而引发错误。

编写表达式的有效方法是:

valid = re.compile(r'[^\uFFFE\uFFFF]   # non-characters', re.VERBOSE)

以下是关于如何在解释冗长的角色类时如何发表评论的建议:

r'''
# LOTS is for foo
# _ is a special fiz
# OF-LITERAL is for bar
[^LOTS_OF-LITERAL]
'''

答案 1 :(得分:-1)

注释在正则表达式中并不总是很好用,看起来你的正则表达式引擎正在解析连字符作为正则表达式的一部分。你不能依赖于没有在这里解析的评论。在实现此代码之前,这是一件好事。