语法
常用匹配规则
通过py中的re模块来学习并使用正式表达式
import re
匹配字符
符号 | 说明 |
---|---|
. | 匹配任意一个字符,除了换行符\n |
[abc] | 匹配abc中的任意一个字符 |
\d | 匹配一个数字,即0-9 |
\D | 匹配非数字,即不是数字 |
\s | 匹配空白,即空格,tab键 |
\S | 匹配非空白,除空格,tab键之类的 |
\w | 匹配单词字符,即a-z、A-Z、_(字母数字下划线) |
\W | 匹配非单词字符 |
匹配字符数量
符号 | 说明 |
---|---|
* | 匹配前一个字符出现0次或无限次,即可有可无 |
+ | 出现1次或者无限次,即至少有1次 |
\? | 出现1次或者0次,即要么1次,要么没有 |
{m} | 出现m次 |
{m,} | 至少出现m次 |
{n,m} | 出现从n到m次 |
分组匹配
符号 | 说明 |
---|---|
| | 匹配左右任意一个表达式 |
(ab) | 讲括号中字符作为一个分组 |
\num | 引用分组num匹配到的字符串 |
(?P) | 分组起别名 |
(?P=name) | 引用别名为name分组匹配到的字符串 |
re库
re.complie
re.compile()是用来优化正则的,它将正则表达式转化为对象。re.search(pattern, string)的调用方式就转换为 pattern.search(string)的调用方式,多次调用一个正则表达式就重复利用这个正则对象,可以实现更有效率的匹配
语法格式
re.compile(pattern, flags=0)
- pttern 匹配模式。即要表达的正则表达式
从compile()函数的定义中,可以看出返回的是一个匹配对象,它单独使用就没有任何意义,需要和findall(), search(), match()搭配使用。
实践操作
常规的re.findall的写法是这样写的,但是我们可以结合compile()函数来使用
import re
obj=re.findall(r'1\d{10}','我的手机号码是:152352100000')
print(obj)
输出的结果为:[‘15235210000’]
与compile()函数结合:
import re
patter=re.compile(r'1\d{10}')
obj=patter.findall('我的手机号码是:1523521000077')
print(obj)
re.findall
在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果有多个匹配模式,则返回元组列表,如果没有找到匹配的,则返回空列表
语法格式
re.findall(pattern, string, flags=0)
或
pattern.findall(string[, pos[, endpos]])
- pattern 匹配模式。
- string 待匹配的字符串。
- pos 可选参数,指定字符串的起始位置,默认为 0。
- endpos 可选参数,指定字符串的结束位置,默认为字符串的长度。
实践操作
输出结果为:[‘10086’, ‘10011’]import re #导入re模块
lst=re.findall(r'\d+','我的电话是:10086,她的电话是:10011')#检索字符串中所有的数字
print(lst)
输出结果为:[‘2345’, ‘09098’]import re
lst1=re.findall(r'\d+','ysegsde2345dgtesget09098')
print(lst1)
re.finditer
语法格式
和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。
re.finditer(pattern, string, flags=0)
- pattern 匹配模式。
-
实践操作
import re
item=re.finditer(r'\d+','我的电话是:10086,她的电话是:10011')
for i in item:
print(i.group()) #要通过group来取数据
re.sub
语法格式
re.sub(pattern, repl, string, count=0, flags=0)
pattern : 正则中的模式字符串。
- repl : 替换的字符串,也可为一个函数。
- string : 要被查找替换的原始字符串。
- count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
flags : 编译时用的匹配模式,数字形式。
1).re.I(re.IGNORECASE): 忽略大小写
2).re.M(MULTILINE): 多行模式,改变'^'和'$'的行为
3).re.S(DOTALL): 点任意匹配模式,改变'.'的行为
4).re.L(LOCALE): 使预定字符类 \w \W \b \B \s \S 取决于当前区域设定
5).re.U(UNICODE): 使预定字符类 \w \W \b \B \s \S \d \D 取决于unicode定义的字符属性
6).re.X(VERBOSE): 详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释
实践操作
#re.sub 实现目标的搜索和查找 2021-12-13
data='Pyhton是很受欢迎的编程语言'
res=re.sub(r'[a-zA-Z]+','C#',data) #字符集的范围+号代表字符模式出现1次以上
print(res)
输出结果为:C#是很受欢迎的编程语言
# 将里面的分数都替换成100分
msg='语文=99,数学=78,英语=90'
m=re.sub(r'\d+','100',msg)
print(m)
输出结果为:语文=100,数学=100,英语=100
import re
data='save your time'
res=re.sub('s','S',data) #讲小s替换成大写的S
print(res)
re.macth
尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none
匹配成功re.match方法返回一个匹配的对象,否则返回None。可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式语法格式
re.match(pattern, string, flags=0)
pattern 匹配模式。
- string 待匹配的字符串。
实践操作
在起始位置匹配
输出结果为:import re
s=re.match(r'\d+','12353442wwww上的人人dddd234g') #从头开始,是否符合是数字要求,如果是,返回数字,如果不是,返回none
print(s)
如果要正常的输出,加上一个.group()<_sre.SRE_Match object; span=(0, 8), match='12353442'> #表示有匹配对象
输出结果为:12353442import re
s=re.match(r'\d+','12353442wwww上的人人dddd234g') #从头开始,是否符合是数字要求,如果是,返回数字,如果不是,返回none
print(s.group())
在起始位置不匹配
import re
s=re.match(r'\d+','wwww上的人人dddd234g') #从头开始,是否符合是数字要求,如果是,返回数字,如果不是,返回none
print(s)
re.search
扫描整个字符串并返回第一个成功的匹配。从任何一个地方开始匹配,只匹配一次。
注意:是一次匹配,如果后面还有匹配的也不会查找了。使用group()来获取数据
语法格式
re.search(pattern, string, flags=0)
- pattern 匹配模式。
- string 待匹配的字符串。
实践操作
输出结果为:import re
r=re.search('abc','helabcloabc')
print(r)
如果要正常的输出,加上一个.group()<_sre.SRE_Match object; span=(3, 6), match='abc'> #表示有匹配对象
输出结果为:abcimport re
r=re.search('abc','helabcloabc')
print(r.group())
输出结果为:10086#2022-01-21 search,找到一个结果就返回,返回的结果是match对象,拿到数据需要.group()
import re
item=re.search(r'\d+','我的电话是:10086,她的电话是:10011')
print(item.group())
Match对象有几个常用的方法:group()
: 用于获得一个或多个分组匹配的字符串,当要获得整个匹配的子串时,可直接使用 group()
或 group(0)
span()
: 返回匹配字符串的起始位置start()
:用于获取分组匹配的子串在整个字符串中的起始位置(子串第一个字符的索引),参数默认值为 0;end()
:用于获取分组匹配的子串在整个字符串中的结束位置(子串最后一个字符的索引+1),参数默认值为 0
import re
r=re.search('abc','helabcloabc')
if r:
print(r.group())
print(r.span())
print(r.start())
print(r.end())
输出结果为:
import re
match=re.search(r'([a-z]+) ([a-z]+)','hello Kitty hellobaby hello world')# 注意此时是区分大小写的
if match:
print(match.group(0))
print(match.group(1))#获取第一个分组的字符串
print(match.group(2))#获取第二个分组的字符串
print(match.groups())
输出结果为:
上面的正则表达式表示两组有多个a-z之间的任意字符组成的多个字符串,并且两组之间是有空格的。其中match.groups()
表示的意思是(m.group(1)
, m.group(2)
, …)search
只要找到符合要求的字符串则不会继续查找,但是事实上后面仍然符合正则的仍然是存在的。比如:hello world
要想所有的都获取到,考虑使用findall()