断言匹配的不是字符,而是位置。
1.单词边界 \b ---- 表示一边是单词字符,另一边不是单词字符
>>> import re
>>> print(re.findall(r"\bword\b","there are many words,but no word"))#仅匹配一处
['word']
>>> print(re.findall(r"word","there are many words,but no word"))#words也被匹配上
['word', 'word']
2.行起始位置 ^和\A
>>> print(re.findall(r"(?m)^\w+","first line\nsecond line\nthird line\n"))#多行模式
['first', 'second', 'third']
>>> print(re.findall(r"^\w+","first line\nsecond line\nthird line\n")) #单行模式
['first']
>>> print(re.findall(r"(?m)\A\w+","first line\nsecond line\nthird line\n"))#多行模式下匹配整段文本的第一个单词
['first']
3.结束位置 $和\Z
>>> print(re.findall(r"\w+$","first line\nsecond line\nthird line\n")) #单行模式
['line']
>>> print(re.findall(r"(?m)\w+$","first line\nsecond line\nthird line\n")) #多行模式
['line', 'line', 'line']
>>> print(re.findall(r"(?m)\w+$","first line\nsecond line\nthird line")) #“$”如果没有匹配终止符,则匹配字符串结尾位置
['line', 'line', 'line']
\Z等同与非多行模式下的$,\z不理终止符,只匹配字符串的结尾位置
但是,在python中没有\z,而是用\Z来代替\z
>>> print(re.findall(r"(?m)\w+\Z","first line\nsecond line\nthird line")) #多行模式也只匹配整段的结尾字符
['line']
>>> print(re.findall(r"(?m)\w+\Z","first line\nsecond line\nthird line\n")) #最后一个字符是\n,而不是字符,所以无法匹配
[]
>>> print(re.findall(r"\w+\Z","first line\nsecond line\nthird line")) #同上
['line']
4.环视
(?!...)右侧不允许出现...
(?<!...)左侧不允许出现...
(?=)右侧必须出现
(?<=)左侧必须出现
例:用逗号分隔数字
该例子匹配这样一个位置:它左边必须有一个数字(?<=\d),并且(两个环视挨着表示“与”)右边的整个字符串是3的倍数(?=(\d{3})+(?!\d))。
这里用来匹配右侧整个字符串的也是一个环视————环视的嵌套————要首先满足内部环视的要求。
内部环视要求(\d{3})+之后不能再出现数字字符,因此(\d{3})+(?!\d)表示右侧的整个字符串
>>> a=re.sub(r"(?<=\d)(?=(\d{3})+(?!\d))",",","123456")
>>> a
'123,456'