Python入门-正则表达式

一、字符串类型数据,自带查找功能

#字符串,匹配查找,返回的是下标位置,空格也算占位
info = "www  baidu  com"
print(info.find("baidu"))
print(info.find("www"))
"""  5  0  """

#默认为左边,find查找,也可以使用右边查找rfind
info = "www  111  com  222 www"
print(info.find("www"))
print(info.rfind("www"))
"""0   19 """

#如果查询不到,返回-1,int类型
info = "www  111  com  222 www"
es = info.find("baidu")
print(type(es))
""" -1  <class 'int'>  """

 

二、正则匹配函数-match,search,findall的区别

# 需要先导入re模块
import re

#字符串,匹配查找
info = "www  baidu  com"print("=======re.match方法从头查找==============")
print("从头匹配OK:", re.match("www", info))  # 匹配成功返回match类对象
print("获取从头匹配OK结果:", str(re.match("www", info).span()))  # span获取位置
print("从头不匹配:", re.match("baidu", info))  #不匹配返回None
print("忽略大小写:", re.match("www","WWW.BAIDU.COM", re.IGNORECASE))
print("=======re.search任意位置查找==============")
print("search匹配:",re.search("www",info))
print("search匹配:",re.search("baidu",info))
print("search忽略大小写:", re.search("www","WWW.BAIDU.COM", re.IGNORECASE))

print("=======re.findall全局查找==============")
print("findall匹配:",re.findall("www",info))
print("findall匹配:",re.findall("baidu",info))
print("findall忽略大小写:", re.findall("www","WWW.BAIDU.COM", re.IGNORECASE))

"""
=======re.match方法从头查找==============
从头匹配OK: <re.Match object; span=(0, 3), match='www'>
获取从头匹配OK结果: (0, 3)
从头不匹配: None
忽略大小写: <re.Match object; span=(0, 3), match='WWW'>
=======re.search任意位置查找==============
search匹配: <re.Match object; span=(0, 3), match='www'>
search匹配: <re.Match object; span=(5, 10), match='baidu'>
search忽略大小写: <re.Match object; span=(0, 3), match='WWW'>
=======re.findall全局查找================
findall匹配: ['www']
findall匹配: ['baidu']
findall忽略大小写: ['WWW']
"""

三、findall详细使用

1.查询固定字符串【不常用,可用于判断是否存在】

import re

text = "张三身高: 199, 体重300, 学号123456, 密码6677555"
print(re.findall(r"123456", text)) 
#['123456']
#r:表示这是一个raw字符串,不进行特殊字符转义,参数一:规则,参数二:原字符串

2.查找某一类字符【例如:找出全部数字】

 找出来一个,就加一个,全是一个个。。

import re

text = "张三身高: 199, 体重300, 学号123456, 密码6677555"
print(re.findall(r"\d", text))
print(re.findall(r"[一重号]", text))
print(re.findall(r"[0-9]", text))
print(re.findall(r"[a-z]", text))
"""
['1', '9', '9', '3', '0', '0', '1', '2', '3', '4', '5', '6', '6', '6', '7', '7', '5', '5', '5']
['重', '号']
['1', '9', '9', '3', '0', '0', '1', '2', '3', '4', '5', '6', '6', '6', '7', '7', '5', '5', '5']
[] 找不到就是空列表
"""

3.不想找单个,连在一起的多个【重复某一类字符:例如连在一起的数字】

import re

text = "张三身高: 199, 体重300, 学号123456, 密码6677555"
print(re.findall(r"\d+", text))
print(re.findall(r"\d{2,4}",text))
"""
['199', '300', '123456', '6677555']
['199', '300', '1234', '56', '6677', '555']
+号:   匹配合适的全部
{1,2}:匹配合适的,指定数量
"""

4.找出组合的不连续字符

import re

text = "张三的电话号码是:123456789, 新换的手机号是88997766, 同时家里座机为:121-9989888"
print(re.findall(r"\d{1,3}-\d{5,9}",text))
"""
['121-9989888']
使用拼接方法,并指定数量
"""

 

#复杂情况的拼接方法,使用竖线:|

import re

text = "张三的电话号码是:123456789, 新换的手机号是88997766, 同时家里座机为:121-9989888"
print(re.findall(r"\d{1,3}-\d{7,10}|\d{5,10}",text))
"""
['123456789', '88997766', '121-9989888']
使用\d提取数字,使用{}指定数量范围,使用-确定格式,使用|拼接多种情况
"""

 

5.限定范围是开头还是尾部

import re

text = "张三的电话号码是:123456789, 新换的手机号是88997766, 同时家里座机为:121-9989888"
print(re.findall(r"^\d{5,10}",text))
text = "123456789可能不是,张三的电话号码是:123456789, 新换的手机号是88997766, 同时家里座机为:121-9989888"
print(re.findall(r"^\d{1,3}-\d{7,10}|^\d{5,10}",text))
"""
[]
['123456789']
使用^限定查询的结果,只能使开头位置的,所以第一次没有匹配结果
"""

 

7.内部约束【例如:找出重复字符】

import re

text = "abc11abc qweqwe zxccxz poipoi"
print(re.findall(r"\w{3}", text))
print(re.findall(r"(\w{3})(\1)", text))
"""
['abc', '11a', 'qwe', 'qwe', 'zxc', 'cxz', 'poi', 'poi']
[('qwe', 'qwe'), ('poi', 'poi')]
\w{3}  表示三个字符
(\w{3})表示一个分组
(\1)   表示里面的内容和第一个组相同
"""

 

8.练手项目

res = re.findall("\S+@\S+", text)     #获取电子邮箱
res = re.findall("\d+@qq.com", text)  #获取QQ邮箱
res = re.findall("https://www.+\s*", text)  #获取网址
res = re.findall("[1-9][0-9]{4,}", text)  #获取QQ账号
res = re.findall("\d+.\d+.\d+.\d+", text)  #获取ip 
res = re.findall("(?<=密码)\S+", text)  #获取密码开头的后续字符
res = re.findall("(?=密码)\S+", text)  #获取密码开头的后续字符

 

匹配符号范围

import re

info = "www.baidu.com.17745674567.127.o.0.1.hello.heLLo.heLlo"
print("原始字符串:",info)
print("==========范围内匹配==========")
mark1 = "he[lkn][lkn]o"
mark2 = "he[a-z][a-z]o"
mark3 = "he[a-zA-Z][a-zA-Z]o"

print("匹配[lkn]范围字符:",re.findall(mark1, info, re.I))
print("匹配[a-z]范围字符:",re.findall(mark2, info, re.I))
print("匹配[a-zA-Z]范围字符:",re.findall(mark3, info, re.I))
print("匹配[0-9]范围字符:",re.findall("[0-9]", info, re.I))
print("匹配[^0-9a-t]范围取反匹配:",re.findall("[^0-9a-t]", info, re.I))
"""
原始字符串: www.baidu.com.17745674567.127.o.0.1.hello.heLLo.heLlo
==========范围内匹配==========
匹配[lkn]范围字符: ['hello', 'heLLo', 'heLlo']
匹配[a-z]范围字符: ['hello', 'heLLo', 'heLlo']
匹配[a-zA-Z]范围字符: ['hello', 'heLLo', 'heLlo']
匹配[0-9]范围字符: ['1', '7', '7', '4', '5', '6', '7', '4', '5', '6', '7', '1', '2', '7', '0', '1']
匹配[^0-9a-t]范围取反匹配: ['w', 'w', 'w', '.', 'u', '.', '.', '.', '.', '.', '.', '.', '.', '.']
"""

边界数量匹配

import re

#有边界符号,表示单边位置
#如没有边界符号,表示任意全局匹配
str = "food hello Food"
pat = "fo[ol][dlk]$"
print("============开始结束匹配==============")
pat22 = "^fo[ol][dlk]"
pat33 = "fo[ol][dlk]"
print("匹配开头:", re.findall(pat, str, re.I))
print("匹配结尾:", re.findall(pat22, str, re.I))
print("匹配不限开头结尾:", re.findall(pat33, str, re.I))
print("============多位简写匹配==============")
input_data = "2020-09-09"
mark = "[0-9]{4}-[0-9]{2}-[0-9]{2}" # 使用{}进行多次匹配
print("生日格式匹配为:", re.match(mark, input_data, re.I))
print("============拆分匹配==============")
info = "hjdfkj3243423.4324324kjkl343435353adf"
mark2 = r"\d+"  #加R表示,这是正则匹配,不加理论上也可以
print(re.split(mark2, info))
score = "119.9"
mark3 = r"^[+-]?\d+(\.\d+)?$"
print(re.match(mark3, score, re.I))
print("============逻辑匹配==============")
tel = "(010)-12343234"
"""
7-8位数字:'\d{7,8}'
前三位区号:\d{3,4}
区号+括号:(\d{3,4})
"""
mark4 = r"((\d{3,4})|(\(\d{3,4}\)-))?\d{7,8}"
print(re.match(mark4, tel))
"""
============开始结束匹配==============
匹配开头: ['Food']
匹配结尾: ['food']
匹配不限开头结尾: ['food', 'Food']
============多位简写匹配==============
生日格式匹配为: <re.Match object; span=(0, 10), match='2020-09-09'>
============拆分匹配==============
['hjdfkj', '.', 'kjkl', 'adf']
<re.Match object; span=(0, 5), match='119.9'>
============逻辑匹配==============
<re.Match object; span=(0, 14), match='(010)-12343234'>
"""

 正则匹配模式

#正则匹配模式
import re

data = """    
food is very good
food is very good
food is very good    
"""
mark = "fo{2}d"
mark2 = ".+"
print("多行匹配以及忽略大小写:",re.findall(mark, data, re.I  | re.M)) #多行匹配以及忽略大小写
print("默认匹配,不加其他后缀:",re.findall(mark2, data)) #多行匹配以及忽略大小写
print("修改.匹配任意模式,可匹配换行等任意字符:",re.findall(mark2, data, re.S)) #多行匹配以及忽略大小写
print("忽略空白和注释,进行匹配:",re.findall(mark2, data, re.X)) #多行匹配以及忽略大小写

"""
多行匹配以及忽略大小写: ['food', 'food', 'food']
默认匹配,不加其他后缀: ['    ', 'food is very good', 'food is very good', 'food is very good    ']
修改.匹配任意模式,可匹配换行等任意字符: ['    \nfood is very good\nfood is very good\nfood is very good    \n']
忽略空白和注释,进行匹配: ['    ', 'food is very good', 'food is very good', 'food is very good    ']
"""

分组

#获取数据后,需要再拆分,可以使用分组
import re

info = "id:root, phone:11012341234, bir:2021-09-08"
mark = r"(\d{4})-(\d{2})-(\d{2})"
res = re.search(mark, info)
print("获取分组数据为 :", res.group())
print("获取第1组数据为:", res.group(1))
print("获取第2组数据为:", res.group(2))
print("获取第3组数据为:", res.group(3))
mark2 = r"\d{4}-\d{2}-\d{2}"
res2 = re.search(mark2, info)
print("不加分组括号为 :",res2.group())

"""
获取分组数据为 : 2021-09-08
获取第1组数据为: 2021
获取第2组数据为: 09
获取第3组数据为: 08
不加分组括号为 : 2021-09-08
"""

环视

# 通过获取指定字符串位置,然后达到匹配目的字符

import re
info = "id:root,name:tom,age:33,id:root"
mark = r"(?<=id:)(?P<name>\w+)"
print(re.findall(mark, info))

"""
['root', 'root']
"""

 

posted @ 2021-08-23 15:15  zwx901323  阅读(180)  评论(0)    收藏  举报