一、正则表达式
正则:用来匹配字符串的一门表达式语言
1.正则支持普通字符
2.元字符(一个字符来匹配一堆内容)
\d 能够匹配一个数字(0-9) \w 能够匹配数字、字母、下划线(0-9, a-z, A-Z, _) \W 除了数字、字母、下划线以外的内容 \D 除了数字以外的内容 [abc] 匹配a, b, c [^abc] 除了a, b, c的内容 . 除了换行符以外的其他所有内容都可以被匹配
3.量词(控制前面元字符出现的频次)
+表示前面的元字符出现1次或多次 *表示前面的元字符出现0次或多次,贪婪匹配的,尽可能多的拿到数据 ?表示前面的元字符出现0次或1次 [\u4e00-\u9fa5] 表示匹配中文字符
4.惰性匹配(爬虫重点)
二、Python内置模块re
import re
result1 = re.findall(r"\d+","山有木兮1木有枝99") #拿到的是列表
result2 = re.search(r"\d+","山有木兮1木有枝99") #只拿到第一个结果就返回
result3 = re.finditer(r"\d+","山有木兮1木有枝99") #把所有的结果放再迭代器里
for item in result3:
print(item.group()) # 从match对象中拿到数据,需要group()
#预加载
obj = re.compile(r"\d+")
result4 = obj.findall("山有木兮1木有枝99")
#爬虫的应用
s="""
<div class="abc">
<div><a rel="nofollow" href="baidu.com">我是百度</a></div>
<div><a rel="nofollow" href="qq.com">我是腾讯</a></div>
<div><a rel="nofollow" href="163.com">我是网易</a></div>
</div>
"""
obj=re.compile(r'<div><a rel="nofollow" href="(?P<url>.*?)">(?P<txt>.*?)</a></div>')
result=obj.finditer(s)
for item in result:
url=item.group('url')
txt=item.group('txt')
print(url,txt)
print(item.groupdict()) #输出入下图所示
三、Python中flags编译标志位
Python中flags 编译标志位,用于修改正则表达式的匹配方式,如:是否区分大小写,对多行数据进行匹配等。常用的flags如下:
(1)re.I 使匹配对大小写不敏感,如下:
# re.I 的学习,忽略大小写
S1 = 'CoN' #定义字符串i1
S2 = 'www.xiao.con' #定义字符串i2
#print(re.search('CoN','www.xiao.con').group()) #区分大小写的子组输出,报有错
print(re.search(S1,S2,re.I).group()) #不区分大小写的子组输出
结果: 输出 con 备注:输出字符的大小以被匹配的字符串的大小写为主,如S2为’www.xiao.CON’,则输出的为:CON (2)re.M 使用^ 和 $ 符号,实现多行多行匹配。如将所有行的末尾字符串输出得:
# re.M 的学习,将所有行的尾字母或者首部输出
S3 = '''I am girl
you are boy
we are friends
''' #定义初始字符串
print(re.findall(r"\w+$",S3,re.M)) #输出S3的每行最后一个字符串
# 输出为:['girl','boy','friends']
(3)re.S匹配包括换行在内的所有字符。如下:
s1 = '''jduedhhelloworld:
11630
passgrthgdg
''' #初始字符串,有换行所以用三引号
b = re.findall('hello(.*?)pass',s1) #findal返回字符串中某个正则表达式模式全部的非重复出现的情况,不包含换行,返回列表
c = re.findall('hello(.*?)pass',s1,re.S) #包含换行
print('b is',b) #输出B匹配的结果 #输出结果:b is []
print('c is',c) #输出C,包行匹配输出的结果 #输出结果:c is ['world: \n 11630\n ']
总结:flags 编译标志位就相当于一些特殊的指令,就如上面提的比如是否忽略大小写。并不是必须使用,不用的时候定义flags=0即可。
四、Python中re.group()
正则表达式中,group()用来提出分组截获的字符串,()用来分组,既然()有如此的功能,我们在正则表达式中匹配‘(’和‘)’,要用‘\’对其转义
正则表达式中的三组括号把匹配结果分成三组
- group() 同group(0)就是匹配正则表达式整体结果
- group(1) 列出第一个括号匹配部分
- group(2) 列出第二个括号匹配部分
- group(3) 列出第三个括号匹配部分。
- groups() 表示从group(1)开始往后的所有值,组合成一个元组类型的值
- group() 表示取全部匹配的字符串或者指定的组,返回结果是一个字符串
import re
a = "123abc456"
# 没有匹配成功的,re.search()返回None
print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0)) # 123abc456,返回整体
print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1)) # 123
print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2)) # abc
print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3)) # 456
print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).groups()) # ('123', 'abc', '456')
print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group()) # 123abc456
五、例子
1.读取txt文件中的中文
# -*- coding:utf-8 -*-
import sys
import re
with open('./text.txt', 'r',encoding = "utf-8") as f:
temp=f.readlines()
title="".join(re.findall(r'[a-zA-Z0-9\u4E00-\u9FA5]+',temp[0]))
content=""
for i in temp[1:]:
content+="".join(re.findall(r'[\u4E00-\u9FA5]+',i))
if __name__=="__main__":
print(title,content,sep='\n')
标签:search,group,re,Python,正则表达式,字符串,print,匹配
From: https://blog.51cto.com/u_15944471/6038326