Python正则表达式

Python正则表达式

1.正则表达式字符串是由普通字符和元字符表示。

①元字符 ②普通字符

基本元字符
字符 说明
转义符,表示转义
. 表示任意一个字符
+ 表示重复一次或多次
* 表示重复零次或多次
? 表示重复零次或一次
| 选择符号,表示“或关系“,例如:A|B表示匹配A或B
{ } 定义量词
[ ] 定义字符类
( ) 定义分组
^ 可以表示取反,或匹配一行的开始
$ 匹配一行的结束

当以^开始时,要求一行字符串的开始位置匹配;当以$结束时,要求一行字符串的结束位置匹配。所以正则表达式w+@zhi jieketang.com和^w+@zhi jieketang.com$是不同的。

import re

p1=r'w+@zhijieketang.com'
p2=r'^w+@zhijieketang.com$'

text = "Tony's email is tony_guan588@zhijieketang.com."
m = re.search(p1,text)
print(m)

m = re.search(p2,text)
print(m)

email = 'tony_guan588@zhijieketang.com'
m = re.search(p2,email)
print(m)

函数

re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。

import re 
print(re.match('www', 'www.runoob.com').span())  # 在起始位置匹配 
print(re.match('com', 'www.runoob.com'))         # 不在起始位置匹配
#输出结果
(0,3)
None

re.search 扫描整个字符串并返回第一个成功的匹配。

import re
print(re.search('www', 'www.runoob.com').span())  # 在起始位置匹配
print(re.search('com', 'www.runoob.com').span())         # 不在起始位置匹配
#输出结果
(0, 3)
(11, 14)

re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。

findall在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。

import re
 
pattern = re.compile(r'd+')   # 查找数字
result1 = pattern.findall('runoob 123 google 456')
result2 = pattern.findall('run88oob123google456', 0, 10)
 
print(result1)
print(result2)
#输出结果
['123', '456']
['88', '12']

re.finditer和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。

import re
 
it = re.finditer(r"d+","12a32bc43jf3") 
for match in it: 
    print (match.group() )
 # 输出结果
12 
32 
43 
3

split 方法按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下:

re.split(pattern, string[, maxsplit=0, flags=0])

pattern:匹配的正则表达式

string:要匹配的字符串。

maxsplit:分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数。

flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

import re
p = r'd+'
text = 'AB12CD34EF'
clist = re.split(p,text)
print(clist)
clist = re.split(p,text,maxsplit=1)  #最大分隔一次
print(clist)
clist = re.split(p,text,,maxsplit=2)  #最大分隔两次
print(clist)
#输出结果
['AB','CD','EF']
['AB','CD34EF']
['AB','CD','EF']

re.sub用于替换字符串中的匹配项。

re.sub(pattern, repl, string, count=0, flags=0)
  • pattern : 正则中的模式字符串。
  • repl : 替换的字符串,也可为一个函数。
  • string : 要被查找替换的原始字符串。
  • count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
import re
p = r'd+'
text = 'AB12CD34EF'
repace_text = re.sub(p,'',text)
print(repace_text)
#输出结果
ABCDEF

compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。编译的正则表达式可以重复使用,减少正则表达式解析和验证,提高效率。

re.compile(pattern[, flags])
  • pattern : 一个字符串形式的正则表达式
  • flags : 可选,表示匹配模式,比如忽略大小写,多行模式等,具体参数为:
    1. re.I 忽略大小写
    2. re.L 表示特殊字符集 w, W, , B, s, S 依赖于当前环境
    3. re.M 多行模式
    4. re.S 即为 . 并且包括换行符在内的任意字符(. 不包括换行符)
    5. re.U 表示特殊字符集 w, W, , B, d, D, s, S 依赖于 Unicode 字符属性数据库
    6. re.X 为了增加可读性,忽略空格和 # 后面的注释
>>>import re
>>> pattern = re.compile(r'd+')                    # 用于匹配至少一个数字
>>> m = pattern.match('one12twothree34four')        # 查找头部,没有匹配
>>> print m
None
>>> m = pattern.match('one12twothree34four', 2, 10) # 从'e'的位置开始匹配,没有匹配
>>> print m
None
>>> m = pattern.match('one12twothree34four', 3, 10) # 从'1'的位置开始匹配,正好匹配
>>> print m                                         # 返回一个 Match 对象
<_sre.SRE_Match object at 0x10a42aac0>
>>> m.group(0)   # 可省略 0
'12'
>>> m.start(0)   # 可省略 0
3
>>> m.end(0)     # 可省略 0
5
>>> m.span(0)    # 可省略 0
(3, 5)

字符类

正则表达式中可以使用字符类,一个字符类定义一组字符,其中的任一字符出现在输出字符串中即匹配成功。注意每次匹配只能匹配字符类中的一个字符。

1.定义字符类

定义一个普通的字符类需要使用'['和']'元字符类。

import re
# 在输入字符串中匹配Java或java,可以使用正则表达式[Jj]ava。
p = r'[Jj]ava
m = re.search(p,'I like Java and Python')
print(m)
m = re.search(p,'I like JAVA and Python')
print(m)
m = re.search(p,'I like java and Python')
print(m)

2.字符类取反

有时需要在正则表达式中指定不想出现的字符,可以在字符类前加"^"符号。

import re
#表示非数字
p = r'[^0123456789]''
m = re.search(p,'1000')
print(m)
m = re.search(p,'Python 3')
print(m)
#遇到第一个匹配的就返回

3.区间

区间是用连字符(-)表示的,[0123456789]采用区间表示[0-9],[^0123456789]采用区间表示[^0-9]。[A-Za-z0-9]表示任何字母和数值字符类,[0-25-7]表示0、1、2、5、6、7几个字符组成的字符类。

import re 
m = re.search(r'[A-Za-z0-9]'','A10.3')
print(m)
m = re.search(r'[0-25-7],'A34879C')
print(m)
#输出结果
<_sre.SRE_Match object;span=(0,1),match='A'>
<_sre.SRE_Match object;span=(4,5),match='7'>

4.预定义字符类

字符 说明
. 匹配任意一个字符
\ 匹配反斜杠字符
匹配换行
匹配回车
f 匹配一个换页符
匹配一个水平制表符
v 匹配一个垂直制表符
s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ f v]。
S 匹配任何非空白字符。等价于 [^ f v]。
d 匹配一个数字字符。等价于 [0-9]。
D 匹配一个非数字字符。等价于 [^0-9]。
w 匹配任何语音的单词字符(如:英文字母、亚洲文字等)、数字和下划线(_)等字符。如果正则表达式编译标志设置为ASCII,则只匹配'[A-Za-z0-9_]'。
W 等价于 '[^w]'。

量词

表示字符或字符串重复的次数。

字符 说明
出现零次或一次
* 出现零次或多次
+ 出现一次或多次
{n} 出现零次或n次
{n,m} 至少出现n次但不超过m次
{n,} 至少出现n次

贪婪量词会尽可能多地匹配字符;懒惰量词尽可能少地匹配字符。大多数计算机语言的正则表达式量词默认是贪婪的,要想使用懒惰量词可以在量词后面加“?”即可。

import re
# 使用贪婪量词
m = re.search(r'd{5,8}','87654321')     #出现数字8次
print(m)  #匹配字符'87654321'
# 使用惰性量词
m = re.search(r'd{5,8}?','87654321')     #出现数字5次
print(m)  #匹配字符'87654'
#输出结果
<_sre.SRE_Match object;span=(0,8),match='87654321'>
<_sre.SRE_Match object;span=(0,5),match='87654'>

分组

如果想让一个字符串作为整体使用量词,可将这个字符串放到一对小括号中,这就是分组。

import re 
p = r'(121){2}''
m = re.search(p,'121121abcabc')
print(m)
print(m.group())   #返回匹配的字符串
print(m.groups())  #返回所有组的内容

p = r'(d{3,4})-(d{7,8})'
m = re.search(p,'010-87654321')
print(m)
print(m.group())   #返回匹配的字符串
print(m.groups())
# 输出结果
<_sre.SRE_Match object;span=(0,6),match='121121'>
121121
('121',)
<_sre.SRE_Match object;span=(0,12),match='010-87654321'>
010-87654321
('010','87654321')

1.对正则表达式进行分组不仅可以对一个字符串整体使用量词,还可以在正则表达式中引用已经存在的分组。

2.在Python程序中访问分组时,除了可以通过组编号进行访问,还可以通过组名进行访问,前提是要在正则表达式中为组命名。组命名语法是在分组的左小括号后添加?P<分组名>实现。

3.反向引用分组。除了可以在程序代码中访问正则表达式匹配之后的分组内容,还可以在正则表达式内部引用之前的分组。

import re
p = r'<([w]+)>.*</1>'
m = re.search(p,'<a>abc</a>')
print(m)
m = re.search(p,'<a>abc</b>')
print(m)
# 输出结果
<_sre.SRE_Match object;span=(0,10),match='<a>abc</a>'>
None

4.非捕获分组

前面介绍的分组称为捕获分组,就是匹配子表达式结果被暂时保存到内存中,以被表达式或其他程序引用,这称之为“捕获”,捕获结果可以通过组编号或组名进行引用。但是有时并不想引用子表达式的匹配结果,不想捕获匹配结果,只是将小括号作为一个整体进行匹配,此时可以使用非捕获分组,非捕获分组在组开头使用“?:"实现。

import re
s = 'img1.jpg,img2.jpg,img3.bmp'
p = r'w+(.jpg)'
m = re.findall(p,s)
print(m)
p = r'w+(?:.jpg)'
m = re.findall(p,s)
print(m)
#输出结果
['.jpg','.jpg']
['img1.jpg','img2.jpg']
原文地址:https://www.cnblogs.com/levelstrcpy/p/14303488.html