在 Programming Collective Intelligence 一书中,有一个正则表达式,
splitter = re.compile('\\W*')
从上下文看来,这匹配任何非字母数字字符。但我很困惑,因为它似乎匹配一个反斜杠,然后是一个或多个 W。它真正匹配的是什么?
您的正则表达式相当于\W*
. 它匹配 0 个或多个非字母数字字符。
实际上,您使用的是 python 字符串文字,而不是原始字符串。在 python 字符串文字中,要匹配文字反斜杠,您需要转义反斜杠 - \\
,因为反斜杠在那里具有特殊含义。然后对于正则表达式,您需要转义两个反斜杠,以使其成为 - \\\\
。
因此,要匹配\
后跟 0 或更多W
,您需要\\\\W*
一个字符串文字。您可以通过使用原始字符串来简化此操作。其中 a\\
将匹配文字\
。这是因为,在原始字符串中使用反斜杠时,不会以任何特殊方式处理。
以下示例将帮助您理解这一点:
>>> s = "\WWWW$$$$"
# Without raw string
>>> splitter = re.compile('\\W*') # Match non-alphanumeric characters
>>> re.findall(splitter, s)
['\\', '', '', '', '', '$$$$', '']
>>> splitter = re.compile('\\\\W*') # Match `\` followed by 0 or more `W`
>>> re.findall(splitter, s)
['\\WWWW']
# With raw string
>>> splitter = re.compile(r'\W*') # Same as first one. You need a single `\`
>>> re.findall(splitter, s)
['\\', '', '', '', '', '$$$$', '']
>>> splitter = re.compile(r'\\W*') # Same as 2nd. Two `\\` needed.
>>> re.findall(splitter, s)
['\\WWWW']
第一个反斜杠只是作为转义字符,用于没有良好的正则表达式字符串表示的编程语言(例如:Java)。在 Python 中你可以做得更好,这是等价的:
r'\W*'
请注意r
开头的 (原始字符串),这使得不必要地使用第一个\
转义字符。第二个\
是不可避免的,这是字符类的一部分\W
\
是正则表达式中的转义字符。从左到右\\
表示\
然后\w*
,表示匹配任何非数字加下划线字符。在这种情况下,如果你想要一个\
,你必须写\\\\
。如果您希望正则表达式更加清晰和简单,您可以使用r'\W*'
. 表示原始r
字符串,可以让你少写\
。
这匹配非单词字符,意思不是字母数字或下划线。这编译成 \W 这是 \w 的否定版本,其中 \w 匹配任何单词字符。
因此,您认为它与非字母数字匹配是正确的。
有关特殊正则表达式字符的参考,您可以查看此处。 http://www.regular-expressions.info/reference.html
发生的事情是\
有助于转义字符。所以\\
意思\
。所以你的正则表达式变成(转义后):
\W*
更好的选择是使用:r'\W*'
该正则表达式将匹配一个反斜杠和零个或多个 W。如果要匹配零个或多个非单词字符:
splitter = re.compile(r'\W*')