下面这段复制于贴子“[库/模块档案] Python3 如何优雅的使用正则表达式 ”
————————————————————————————————————————————————————————————————————————————————————————————————————————————
\b
单词边界,这是一个只匹配单词的开始和结尾的零宽断言。“单词”定义为一个字母数字的序列,所以单词的结束指的是空格或者非字母数字的字符。
下边例子中,class 只有在出现一个完整的单词 class 时才匹配;如果出现在别的单词中,并不会匹配。
>>> p = re.compile(r'\bclass\b')
>>> print(p.search('no class at all'))
<_sre.SRE_Match object; span=(3, 8), match='class'>
>>> print(p.search('the declassified algorithm'))
None
>>> print(p.search('one subclass is'))
None
复制代码
在使用这些特殊的序列的时候,有两点是需要注意的:第一点需要注意的是,Python 的字符串跟正则表达式在有些字符上是有冲突的(回忆之前反斜杠的例子)。比如说在 Python 中,\b 表示的是退格符(ASCII 码值是 8)。所以,你如果不使用原始字符串,Python 会将 \b 转换成退格符处理,这样就肯定跟你的预期不一样了。
下边的例子中,我们故意不写表示原始字符串的 'r',结果确实大相庭径:
>>> p = re.compile('\bclass\b')
>>> print(p.search('no class at all'))
None
>>> print(p.search('\b' + 'class' + '\b'))
<_sre.SRE_Match object; span=(0, 7), match='\x08class\x08'>
复制代码
第二点需要注意的是,在字符类中不能使用这个断言。跟 Python 一样,在字符类中,\b 只是用来表示退格符。
__________________________________________________________________________________________________________________________________
一、这里说的“第二点需要注意的”不是很明白,这第二点需要注意说的内容,是不是和第一点重复了?
二、还有这个“字符类”和“字符串”有差别吗?
第一点需要注意的是,Python 的字符串跟正则表达式在有些字符上是有冲突的,比如在Python中, \b 表示退格符(ASCII码值为8)。因此,如果你不使用原始字符串(以 r 为前缀),Python会将 \b 转换成退格符处理,这可能与你的预期不一致。
在第一个例子中, \b 被正确地用作单词边界,因为使用了原始字符串 r'\bclass\b' 。
import re
p = re.compile(r'\bclass\b')
print(p.search('no class at all'))
然而,在下一个例子中, \b 被解释为退格字符,因为没有使用原始字符串,导致匹配失败:
p = re.compile('\bclass\b')
print(p.search('no class at all'))
print(p.search('\b' + 'class' + '\b'))
第二点需要注意的是, \b 在字符类中不能用作单词边界。在字符类内部, \b 只是表示退格符,而不再具有单词边界的特殊含义。
关于你的问题:
1. 是的,第一点和第二点的内容存在一定的重复,都涉及到了在不同上下文中处理 \b 的问题,但是它们强调的是不同的方面。第一点是关于字符串内部的处理,第二点是关于字符类内部的处理。
2. "字符类" 和 "字符串" 在这里确实有差别。在正则表达式中,字符类是用方括号 [] 包围的字符集合,例如 [a-z] 表示匹配任意小写字母。而字符串是指正则表达式要匹配的具体文本内容。在字符类内部,特殊字符如 \b 会失去其特殊含义,而在字符串中, \b 可以用于表示单词边界。
|