正则表达式

文章目录

正则表达式基础

1、为什么使用正则

我这里拿一个例子说明,我们一般做数据处理的时候,会遇到电话号码的情况。

我们一般的处理方法如下:

python 复制代码
def isPhone(phone):
    # 长度为11
    # 全部都是数字字符
    # 以1开头
    pass

if isPhone("13812345678"):
    print("是手机号")
else:
    print("不是手机号")

使用正则表达式解决的话

python 复制代码
import re

def isPhone(phone):
    # 正则表达式解释:
    # ^        匹配字符串的开始
    # 1        手机号码以1开头
    # [2-9]    第二位是2到9之间的数字
    # \d{9}    后面跟着9个数字(\d 表示数字,{9} 表示重复9次)
    # $        匹配字符串的结束
    pattern = r'^1[2-9]\d{9}$'
    if re.fullmatch(pattern, phone):
        return True
    else:
        return False

# 测试函数
if isPhone("13812345678"):
    print("是手机号")
else:
    print("不是手机号")

这里可以看出正则表达式是一种用于匹配字符串中字符组合的模式,它在文本处理和字符串分析中非常有用。

2、正则与re模块简介

则表达式是一种强大的文本处理工具,用于搜索、替换、检查或解析特定模式的字符串。正则表达式使用单个字符串来描述、匹配和处理一系列符合某个句法规则的字符串。

Python 的 re 模块提供了对正则表达式的全面支持,包括编译正则表达式、执行匹配检查、搜索和替换文本等功能。

如下四个方法经常使用

  • match()
  • search()
  • findall()
  • finditer()

正则表达式

我现在列出一个表格,大家可以看一下常用的匹配模式

1、匹配单个字符

python 复制代码
# []  # 原子表
[a]
[ab]  # 匹配a或者b
[abc]  # 匹配a或者b后者c
[123]  # 匹配1或者2或者3
[0-9]  # 匹配任意一位数字
[a-z]  # 匹配任意以为小写字母
[A-Z]  # 匹配任意一位大写字母
[a-zA-Z]  # 匹配任意大小写字母

# [][]
[abc][0-9]  # 它代表什么意思?  匹配a或者b后者c和任意一位数字  a1

# 匹配手机号码
1[3-9][0-9]{9}   # {9} 代表前面的[0-9]9位

# ^ 限制开头  $ 限制结尾  一般用于组合
^1[3-9][0-9]{9}$  # 完全匹配  匹配的字符串中 必须完全符合才算匹配成功
15611833906  # 符合
156118339067  # 不符合

# {} 代表前面正则匹配的n词
[a-z]{2}  # 匹配俩位小写字母
[a-z][a-z]  # 等同于上方

# {m,n}  m-n之间的
[a-z]{2,5}  # 匹配2-5个小写字母

# {m,}  # 至少m个
[a-z]{2,}  # 至少匹配2个小写字母

# ? 可有可无
-?[1-9]   # 匹配正负1-9

# .  匹配换行符以外的任意字符
a  x  z

# * 代表前面的0次到多次  {0,}


# .* 组合 了解  贪婪模式  匹配换行符以外的任意字符任意次

# .*? 组合 重要!!!!!!   非贪婪模式 匹配换行符以外的任意字符任意次

# +  匹配一次到多次  {1,}

# .+?  非贪婪模式 匹配换行符以外的任意字符至少1次

# |  代表或
[a-z]|[0-9] # 匹配字母或数字

# ()  # 1.作为一个单元   2.作为子存储

2、匹配锚字符

  • ^ 行首锚:
    匹配字符串的开始位置。
python 复制代码
import re
pattern = re.compile('^hello')
print(re.search(pattern, "hello world").group())
  • $ 行尾锚:
    匹配字符串的结束位置。
python 复制代码
pattern = re.compile('world$')
print(re.search(pattern, "Hello world").group())
  • \A 字符串开始锚:
    匹配字符串的绝对开始位置,与 ^ 类似,但不受多行匹配的影响。
java 复制代码
text = "Hello\nWorld"
pattern = re.compile(r'\AHello')
# 这里会匹配,因为 'Hello' 在字符串的绝对开始位置
result = pattern.search(text)

3、限定符

python 复制代码
import re

# (xyz) 匹配括号内的xyz,作为一个整体去匹配
pattern_group = re.compile(r'(xyz)')
result_group = pattern_group.search("The string contains xyz.")
if result_group:
    print("Group matched:", result_group.group())  # 输出: Group matched: xyz

# x? 匹配0个或者1个x,非贪婪匹配
pattern_optional = re.compile(r'x?')
result_optional = pattern_optional.search("hello")
if result_optional:
    print("Optional matched:", result_optional.group())  # 输出: Optional matched: 

# x* 匹配0个或任意多个x
pattern = re.compile('h*')
print(re.search(pattern,"hello world")): 

# x+ 匹配至少一个x
pattern_plus = re.compile(r'x+')
result_plus = pattern_plus.search("hello")
if result_plus:
    print("Plus matched:", result_plus.group())  # 输出: Plus matched: lo

# x{n} 确定匹配n个x,n是非负数
pattern_fixed = re.compile(r'x{3}')
result_fixed = pattern_fixed.search("xxxx")
if result_fixed:
    print("Fixed matched:", result_fixed.group())  # 输出: Fixed matched: xxx

# x{n,} 至少匹配n个x
pattern_at_least = re.compile(r'x{2,}')
result_at_least = pattern_at_least.search("xxxx")
if result_at_least:
    print("At least matched:", result_at_least.group())  # 输出: At least matched: xxxx

# x{n,m} 匹配至少n个最多m个x
pattern_range = re.compile(r'x{1,3}')
result_range = pattern_range.search("xxxx")
if result_range:
    print("Range matched:", result_range.group())  # 输出: Range matched: xxx

# x|y \|表示或的意思,匹配x或y
pattern_alternative = re.compile(r'x|y')
result_alternative = pattern_alternative.search("x")
if result_alternative:
    print("Alternative matched:", result_alternative.group())  # 输出: Alternative matched: x

re模块中常用函数

1、match()函数

  • 功能

    获取成功返回 匹配的对象

  • 参数

参数 说明
pattern 匹配的正则表达式(一种字符串的模式)
string 要匹配的字符串
flags 标识位,用于控制正则表达式的匹配方式
python 复制代码
import re

res = re.match('\d{2}','123')
print(res.group())
print(res.span())

#给当前匹配到的结果起别名
s = '3G4HFD567'
re.match("(?P<value>\d+)",s)
print(x.group(0))
print(x.group('value'))

2、searce()函数

  • 功能
    扫描整个字符串string,并返回第一个pattern模式成功的匹配

匹配失败 返回 None

  • 参数
    | 参数 | 说明 |
    | ------- | ------------------------------------ |
    | pattern | 匹配的正则表达式(一种字符串的模式) |
    | string | 要匹配的字符串 |
    | flags | 标识位,用于控制正则表达式的匹配方式 |
python 复制代码
import re

res = re.search('[a-z]', '131A3ab889s')
print(res)
print(res.group()

3、findall()函数(返回列表)

参数 说明
pattern 匹配的正则表达式(一种字符串的模式)
string 要匹配的字符串
flags 标识位,用于控制正则表达式的匹配方式
python 复制代码
myStr = """
<a href="http://www.baidu.com">百度</a>
<A href="http://www.taobao.com">淘宝</A>
<a href="http://www.id97.com">电
影网站</a>
<i>我是倾斜1</i>
<i>我是倾斜2</i>
<em>我是倾斜2</em>
"""
# html里是不区分大小写
# (1)给正则里面匹配的 加上圆括号 会将括号里面的内容进行 单独的返回
res = re.findall("(<a href=\"http://www\.(.*?)\.com\">(.*?)</a>)",myStr) #[('<a href="http://www.baidu.com">百度</a>', 'baidu', '百度')]

# 括号的区别
res = re.findall("<a href=\"http://www\..*?\.com\">.*?</a>",myStr) #['<a href="http://www.baidu.com">百度</a>']

#(2) 不区分大小写的匹配
res = re.findall("<a href=\"http://www\..*?\.com\">.*?</a>",myStr,re.I) #['<a href="http://www.baidu.com">百度</a>', '<A href="http://www.taobao.com">淘宝</A>']
res = re.findall("<[aA] href=\"http://www\..*?\.com\">.*?</[aA]>",myStr) #['<a href="http://www.baidu.com">百度</a>']

4、finditer()函数

功能

与findall()类似,返回一个迭代器

参数

参数 说明
pattern 匹配的正则表达式(一种字符串的模式)
string 要匹配的字符串
flags 标识位,用于控制正则表达式的匹配方式
python 复制代码
import re

res = re.finditer('\w', '12hsakda1')
print(res)
print(next(res))

for i in res:
    print(i)

5、split()函数

  • 作用:切割字符串
  • 参数
    pattern 正则表达式

string 要拆分的字符串

maxsplit 最大拆分次数 默认拆分全部

flags 修正符

python 复制代码
import re
myStr = "asdas\rd&a\ts12d\n*a3sd@a_1sd"
#通过特殊字符 对其进行拆分 成列表
res = re.split("[^a-z]",myStr)
res = re.split("\W",myStr)

6、修正符

  • 属性

re.I 不区分大小写匹配

python 复制代码
print(re.findall('[a-z]','AaBb'))
print(re.findall('[a-z]','AaBb', flags=re.I))

re.M 多行匹配 影响到^ 和 $ 的功能

python 复制代码
myStr = """asadasdd1\nbsadasdd2\ncsadasdd3"""
print(re.findall('^[a-z]',myStr, ))
print(re.findall('\A[a-z]',myStr))
print(re.findall('\d$',myStr))
print(re.findall('\d\Z',myStr))
# re.M
print(re.findall('^[a-z]',myStr, flags=re.M))
print(re.findall('\A[a-z]',myStr, flags=re.M))
print(re.findall('\d$',myStr, flags=re.M))
print(re.findall('\d\Z',myStr, flags=re.M))

re.S 使.可以匹配换行符 匹配任意字符

python 复制代码
print(re.findall('<b>.*?</b>','<b>b标签</b>'))
print(re.findall('<b>.*?</b>','<b>b标\n签</b>', flags=re.S))

综合案例

1、匹配年.txt

初始文件

text 复制代码
124528	男	14年	2012年5月以前	路人(0)	2017/02/21
2
顺便签约客服
940064306	男	9年	2016/07/12	宗师(1285)	2017/06/26
3
世间尽是妖魔鬼怪"(oДo*)
90年代的新一辈_
1193887909	男	7年	2016/10/17	宗师(1084)	2017/06/26
4
萧十三楼
905519160	男	9年	2016/07/08	宗师(972)	2017/06/24
5
石头哥
北京-php-石头
2669288101	男	2年	2016/06/17	宗师(772)	2017/06/23
6
       缄默。+
       
1393144035	未知	7年	2016/10/08	宗师(754)	2017/06/25
7

匹配具体的年

python 复制代码
res = re.findall("\t(\d{1,2}年)",myStr)

匹配具体的年月日

python 复制代码
res = re.findall("[0-9]{4}/[0-9]{2}/[0-9]{2}",myStr)

2、匹配邮箱手机号.txt

text 复制代码
	caoxigang@baidu.com
曹 艳	Caoyan	6895	13811661805	caoyan@baidu.com
曹 宇	Yu Cao	8366	13911404565	caoyu@baidu.com
曹 越	Shirley Cao	6519	13683604090	caoyue@baidu.com
曹 政	Cao Zheng	8290	13718160690	caozheng@baidu.com
查玲莉	Zha Lingli	6259	13552551952	zhalingli@baidu.com
查 杉	Zha Shan	8580	13811691291	zhashan@baidu.com
查 宇	Rachel	8825	13341012971	zhayu@baidu.com
柴桥子	John	6262	13141498105	chaiqiaozi@baidu.com
常丽莉	lily	6190	13661003657	changlili@baidu.com
车承轩	Che Chengxuan	6358	13810729040	chechengxuan@baidu.com
陈 洁	Che	13811696984	chenxi_cs@baidu.com
陈 超	allen	8391	13810707562	chenchao@baidu.com
陈朝辉		13714189826	chenchaohui@baidu.com
陈 辰	Chen Chen	6729	13126735289	chenchen_qa@baidu.com
陈 枫	windy	8361	13601365213	chenfeng@baidu.com
陈海腾	Chen Haiteng	8684	13911884480	chenhaiteng@baidu.com
陈 红	Hebe	8614	13581610652	chenhong@baidu.com
陈后猛	Chen Houmeng	8238	13811753474	chenhoumeng@baidu.com
陈健军	Chen Jianjun	8692	13910828583	chenjianjun@baidu.com
陈 景	Chen Jing	6227	13366069932	chenjing@baidu.com
陈竞凯	Chen Jingkai	6511	13911087971	jchen@baidu.com
陈 坤	Isa13810136756	chenlei@baidu.com
陈 林	Lin Chen	6828	13520364278	chenlin@qq.com


http://bbs.tianya.cn/m/post-140-393974-6.shtml
http://quote.eastmoney.com/stocklist.html
http://quote.stockstar.com/stock/sha.shtml
http://quote.stockstar.com/fund/stock.shtml
下载链接地址
http://quotes.money.163.com/service/chddata.html?code=sh202003&end=20130523&fields=TCLOSE;HIGH;LOW;TOPEN;LCLOSE;CHG;PCHG;TURNOVER;VOTURNOVER;VATURNOVER;TCAP;MCAP

#匹配 手机号

python 复制代码
res = re.findall("[1][3-8]\d{9}",myStr)

匹配 邮箱

python 复制代码
res = re.findall("\w+@.+\.\w+",myStr)

匹配豆瓣内容

标题

python 复制代码
import re
"""
需求
1. 豆瓣图书标题
2. 抓取图片的标签
"""

# 读取数据
f = open('豆瓣.html','r')
data = f.read()
f.close()
"""
<a href="https://book.douban.com/subject/27104959/">离开的,留下的</a>
<a href="https://book.douban.com/subject/26961102/">灵契</a>
<a href="https://book.douban.com/subject/27054039/">寓言</a>
<a href="https://book.douban.com/subject/27139971/">高难度对话:如何与挑剔的人愉快相处</a>
"""
# 正则匹配所有标题
 pattern = re.compile('<a href="https://book.douban.com/subject/\d+/">(.*?)</a>')
 titleList = pattern.findall(data)
 print(titleList)

图片

python 复制代码
import re
path = r"C:\Users\xlg\Desktop\豆瓣.html"
file = open(path,"rb")
data = file.read().decode("utf-8")
file.close()

# print(data)
# <img src="https://img3.doubanio.com/mpic/s29590893.jpg"/>
# <img src="https://img3.doubanio.com/mpic/s29578984.jpg"/>
# pattern = re.compile("<img src=\"https://img3.doubanio.com/mpic/s\d{8}\.jpg\"/>")
pattern = re.compile("<img src=\"https://img[0-9]\.doubanio.com/mpic/\w+\.jpg\"/>")
imgList = pattern.findall(data)

# <img src="https://img1.doubanio.com/mpic/s29533317.jpg"/>
path = r"C:\Users\xlg\Desktop\img.html"
file = open(path,"w")
file.writelines(imgList)
file.close()

匹配简介

python 复制代码
import re
"""
<p class="color-gray">
                        [意] 普里莫·莱维 / [意] 莱昂纳多·德·贝内代蒂 / 中信出版社 / 2017-10
</p>
<p>
                        奥斯维辛集中营幸存者的证词合集,由身为化学家的意大利著名作家普里莫·莱维及其奥斯维辛狱友、外科医生德·贝内代蒂共同整理撰写。
                    </p>
"""
f = open('../素材/豆瓣.html','r')
data = f.read()
f.close()

pattern = re.compile('<p class="color-gray">(.*?)</p>',re.DOTALL)
相关推荐
行走的山峰30 分钟前
etcd三节点,其中一个坏掉了的恢复办法
数据库·etcd
shelby_loo3 小时前
通过 Docker 部署 MySQL 服务器
服务器·mysql·docker
ImomoTo3 小时前
HarmonyOS学习(十三)——数据管理(二) 关系型数据库
数据库·学习·harmonyos·arkts·鸿蒙
机器视觉知识推荐、就业指导6 小时前
Qt/C++事件过滤器与控件响应重写的使用、场景的不同
开发语言·数据库·c++·qt
jnrjian6 小时前
export rman 备份会占用buff/cache 导致内存压力
数据库·oracle
isNotNullX7 小时前
一文解读OLAP的工具和应用软件
大数据·数据库·etl
小诸葛的博客8 小时前
pg入门1——使用容器启动一个pg
数据库
sleP4o9 小时前
Python操作MySQL
开发语言·python·mysql