九、断言

我们想要使用一些匹配规则作为位置,只匹配前面或者后面的内容,那应该怎么实现呢?这就要说道断言了,断言指定了一个位置。有以下几种形式。

(?=…)
匹配 … 的内容。…的开始是匹配的位置。这个叫lookahead assertion。比如,Isaac (?=Asimov) 匹配 ‘Isaac ‘只有在后面是’Asimov’ 的时候。

”(?=…)“的用法

1
2
3
4
5
6
7
8
import re
string = 'test1234@gmail.com或12076879876电话'
pattern1 = re.compile(r'\w(?=12)')   #(?=12)匹配的位置是test1234中的12和12076879876中12,\w的位置是(?=12)前面。"12"的开始字符1是匹配开始位置,所以它获取前面的第一个字符,结果是['t', '或']
pattern2 = re.compile(r'(?=12)\w')   #(?=12)匹配的位置是test1234中的12和12076879876中12,\w的位置是(?=12)后面,"12"的开始字符1是匹配开始位置,所以它获取后面的第一个字符,结果是['1', '1']
item1 = re.findall(pattern1,string)
item2 = re.findall(pattern2,string)
print(item1)
print(item2)

执行以上程序会输出如下结果:

1
2
['t', '或']
['1', '1']

(?!…)
匹配 … 不符合的情况。这个叫negative lookahead assertion(前视取反)。比如说, Isaac (?!Asimov)只有后面不是’Asimov’的时候才匹配 ‘Isaac ’ 。

”(?!…)“的用法

1
2
3
4
5
6
7
8
import re
string = 'test1234@gmail.com或test12076879876电话'
pattern1 = re.compile(r'test(?!120)\w*') #test字符开始的,后面不是120的,尽可能多的匹配。结果test1234。
pattern2 = re.compile(r'(?!120)\w*')  #不是120字符开始的,尽可能多的匹配。
item1 = re.findall(pattern1,string)
item2 = re.findall(pattern2,string)
print(item1)
print(item2)

执行以上程序会输出如下结果:

1
2
['test1234']
['test1234', '', 'gmail', '', 'com或test12076879876电话', '']

(?<=…)
匹配 … 的内容。…的末尾是匹配的位置。这叫positive lookbehind assertion (正向后视断定)。 (?<=abc)def 会在 ‘abcdef’ 中找到一个匹配,因为后视会往后看3个字符并检查是否包含匹配的样式。包含的匹配样式必须是定长的,意思就是 abc 或 a|b 是允许的,但是 a* 和 a{3,4} 不可以。注意以 positive lookbehind assertions 开始的样式,如 (?<=abc)def ,并不是从a开始搜索,而是从d往回看的。

1
2
3
4
5
6
7
8
>>> import re
>>> m = re.search('(?<=abc)def', 'abcdef')
>>> m.group(0)
'def'

>>> m = re.search(r'(?<=-)\w+', 'spam-egg')
>>> m.group(0)
'egg'

”(?<=…)“的用法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import re
string = 'test1234@gmail.com或12076879876电话'
pattern1 = re.compile(r'\w(?<=12)')    #(?=12)匹配的位置是test1234中的12和12076879876中12,\w的位置是(?<=12)前面。"12"的开始字符2是匹配开始位置,所以它获取前面的第一个字符,结果是['2', '2']
pattern2 = re.compile(r'(?<=12)\w')   #(?<=12)匹配的位置是test1234中的12和12076879876中12,\w的位置是(?<=12)前面。"12"的开始字符2是匹配开始位置,所以它获取后面的第一个字符,结果是['3', '0']
pattern3 = re.compile(r'\w\w\w(?<=12)')  #(?=12)匹配的位置是test1234中的12和12076879876中12,\w的位置是(?<=12)前面。"12"的开始字符2是匹配开始位置,所以它获取前面的三个字符,结果是['t12', '或12']
item1 = re.findall(pattern1,string)
item2 = re.findall(pattern2,string)
item3 = re.findall(pattern3,string)
print(item1)
print(item2)
print(item3)

执行以上程序会输出如下结果:

1
2
3
['2', '2']
['3', '0']
['t12', '或12']

(?<!…)
匹配当前位置之前不是 … 的样式。这个叫negative lookbehind assertion(后视断定取非)。类似正向后视断定,包含的样式匹配必须是定长的。可以从字符串搜索开始的位置进行匹配。

可选标志修饰符
正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:

re.A
re.ASCII
让\w, \W, \b, \B, \d, \D, \s 和 \S 只匹配ASCII,而不是Unicode。

“re.A re.ASCII”的用法

1
2
3
4
5
6
7
8
import re
string = 'test1234@gmail.com或13076879876电话'
pattern1 = re.compile(r'\w+')
pattern2 = re.compile(r'\w+',re.A)  #re.A,也可以写成re.ASCII
item1 = re.findall(pattern1,string)
item2 = re.findall(pattern2,string)
print(item1)
print(item2)

执行以上程序会输出如下结果:

1
2
['test1234', 'gmail', 'com或13076879876电话']
['test1234', 'gmail', 'com', '13076879876']

re.DEBUG
显示有关已编译表达式的调试信息。

“re.DEBUG”的用法

1
2
3
4
5
6
7
8
import re
string = 'test1234@gmail.com或13076879876电话'
pattern1 = re.compile(r'\w+')
pattern2 = re.compile(r'\w+',re.DEBUG)  #re.DEBUG
item1 = re.findall(pattern1,string)
item2 = re.findall(pattern2,string)
print(item1)
print(item2)

执行以上程序会输出如下结果:

1
2
3
4
5
max_repeat 1 4294967295
  in
    category category_word
['test1234', 'gmail', 'com或13076879876电话']
['test1234', 'gmail', 'com或13076879876电话']

re.I
re.IGNORECASE
使匹配对大小写不敏感

“re.I re.IGNORECASE”的用法

1
2
3
4
5
6
7
8
import re
string = 'test1234@gmail.com或TEST5678@gmail.com'
pattern1 = re.compile(r'test')
pattern2 = re.compile(r'test',re.I)  #re.I,也可以写成re.IGNORECASE
item1 = re.findall(pattern1,string)
item2 = re.findall(pattern2,string)
print(item1)
print(item2)

执行以上程序会输出如下结果:

1
2
['test']
['test', 'TEST']

re.L
re.LOCALE
做本地化识别(locale-aware)匹配

re.M
re.MULTILINE
多行匹配。^ 和 $ 受影响。

“re.M re.MULTILINE”的用法

1
2
3
4
5
6
7
8
9
import re
string = '''test1234@gmail.com或
test5678@gmail.com'''
pattern1 = re.compile(r'^test\d*')
pattern2 = re.compile(r'^test\d*',re.M)  #re.M,也可以写成re.MULTILINE
item1 = re.findall(pattern1,string)
item2 = re.findall(pattern2,string)
print(item1)
print(item2)

执行以上程序会输出如下结果:

1
2
['test1234']
['test1234', 'test5678']

re.S
re.DOTALL
使 . 匹配包括换行在内的所有字符

re.X
re.VERBOSE
该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。


转载请注明本网址。