在Python中需要通过正则表达式对字符串进行匹配的时候,可以使用一个模块,名字为re。
# 导入re模块
import re
# 使用match方法进行匹配操作
result = re.match(正则表达式,要匹配的字符串)
# 如果上一步匹配到数据的话,可以使用group方法来提取数据
result.group()
In [1]: import re
In [2]: # re.match(正则表达式, 需要处理的字符串)
In [3]: re.match(r"hello", "hello world")
#有返回值,用户的数据符合规范
Out[3]: <_sre.SRE_Match object; span=(0, 5), match='hello'>
#无返回值,用户的数据符合规范
In [4]: re.match(r"hello", "Hello world")
In [5]: re.match(r"[hH]ello", "Hello world")
Out[5]: <_sre.SRE_Match object; span=(0, 5), match='Hello'>
In [6]: re.match(r"[hH]ello", "hello world")
Out[6]: <_sre.SRE_Match object; span=(0, 5), match='hello'>
re.match() 能够匹配出以xxx开头的字符串。
In [8]: re.match(r"速度与激情1", "速度与激情2") #无返回值
In [11]: re.match(r"速度与激情\d", "速度与激情5")
Out[11]: <_sre.SRE_Match object; span=(0, 6), match='速度与激情5'>
In [12]: ret = re.match(r"速度与激情\d", "速度与激情5")
In [13]: ret.group()
Out[13]: '速度与激情5'
In [16]: ret = re.match(r"速度与激情\d", "速度与激情55") #\d只能代表一位数字
In [17]: ret.group()
Out[17]: '速度与激情5'
In [22]: ret = re.match(r"速度与激情[12345678]", "速度与激情1")
In [23]: ret.group()
Out[23]: '速度与激情1'
In [24]: re.match(r"速度与激情[12345678]", "速度与激情1").group()
Out[24]: '速度与激情1'
In [30]: re.match(r"速度与激情[1-8]", "速度与激情3")
Out[30]: <_sre.SRE_Match object; span=(0, 6), match='速度与激情3'>
#中间数字不连续
In [40]: re.match(r"速度与激情[123678]", "速度与激情8")
Out[40]: <_sre.SRE_Match object; span=(0, 6), match='速度与激情8'>
In [42]: re.match(r"速度与激情[1-36-8]", "速度与激情1")
Out[42]: <_sre.SRE_Match object; span=(0, 6), match='速度与激情1'>
In [65]: re.match(r"速度与激情\w", "速度与激情哈").group()
Out[65]: '速度与激情哈'
In [67]: re.match(r"速度与激情\s\d", "速度与激情 1").group()
Out[67]: '速度与激情 1'
In [68]: re.match(r"速度与激情\s\d", "速度与激情\t1").group()
Out[68]: '速度与激情\t1'
In [75]: re.match(r"速度与激情.", "速度与激情#").group()
Out[75]: '速度与激情#'
In [81]: re.match(r"速度与激情\d{1,3}", "速度与激情12").group()
Out[81]: '速度与激情12'
In [82]: re.match(r"速度与激情\d{1,3}", "速度与激情123").group()
Out[82]: '速度与激情123'
如果{
}里面只有一位数字,则{
}前面指定的是什么,必须有多少位
In [88]: re.match(r"\d{11}", "123456A78901").group()
AttributeError: 'NoneType' object has no attribute 'group'
In [91]: re.match(r"021-?\d{8}", "021-12345678").group()
Out[91]: '021-12345678'
In [97]: re.match(r"\d{3,4}-?\d{7,8}", "0532-1234567").group()
Out[97]: '0532-1234567'
三个双引号之间的内容可以换行
In [98]: html_content = """fdsf
...: kasdjfkjasdkfjkasdjfjahsdufhawufhausdhfuahsdf
...: asdjfhjjasdhf"""
In [99]: print(html_content)
fdsf
kasdjfkjasdkfjkasdjfjahsdufhawufhausdhfuahsdf
asdjfhjjasdhf
In [100]: re.match(r".*", html_content).group()
Out[100]: 'fdsf'
In [101]: re.match(r".*", html_content, re.S).group()
Out[101]:"fdsf\nkasdjfkjasdkfjkasdjfjahsdufhawufhausdhfuahsdf\nasdjfhjjasdhf"
In [102]: re.match(r".*", "a").group()
Out[102]: 'a'
In [103]: re.match(r".*", "a1").group()
Out[103]: 'a1'
In [104]: re.match(r".*", "").group()
Out[104]: ''
In [105]: re.match(r".+", "a").group()
Out[105]: 'a'
In [106]: re.match(r".+", "ab").group()
Out[106]: 'ab'
In [107]: re.match(r".+", "abaksdjfkjasdkfjaksdjfkajsdfkjs").group()
Out[107]: 'abaksdjfkjasdkfjaksdjfkajsdfkjs'
In [108]: re.match(r".+", "").group()
AttributeError: 'NoneType' object has no attribute 'group'
def main():
names = ["age", "_age", "1age", "age1", "a_age", "age_1_", "age!", "a#123", "__________"]
for name in names:
# ret = re.match(r"[a-zA-Z_][a-zA-Z0-9_]*", name)
# ^规定开头 $规定结尾
# python中的match默认是从头开始判断的所以,在match中可以不写^,但是match不会判断结尾,所以 # 当需要以xxx结尾的时候,还需要写上$
ret = re.match(r"^[a-zA-Z_][a-zA-Z0-9_]*$", name)
if ret:
print("变量名:%s 符合要求....通过正则匹配出来的数据是:%s" % (name, ret.group()))
else:
print("变量名:%s 不符合要求...." % name)
if __name__ == "__main__":
main()
import re
def main():
email = input("请输入一个邮箱地址:")
# 如果在正则表达式中需要用到了某些普通的字符,比如 . 比如? 等,仅仅需要在他们前面添加一个 反斜杠\进行转义
ret = re.match(r"[a-zA-Z_0-9]{4,20}@163\.com$", email)
if ret:
print("%s符合要求...." % email)
else:
print("%s不符合要求...." % email)
if __name__ == "__main__":
main()
在正则表达式匹配正确的前提下,想要单独取出某一部分数据来,那么把那一部分的数据两边加上()
>>> import re
>>> re.match(r"[a-zA-Z0-9_]{4,20}@163\.com$", "[email protected]").group()
'[email protected]'
>>> import re
>>> re.match(r"[a-zA-Z0-9_]{4,20}@(163|126)\.com$", "[email protected]").group()
'[email protected]'
在正则表达式匹配正确的前提下,想要单独取出某一部分数据来,那么把那一部分的数据两边加上()
>>> import re
>>> re.match(r"[a-zA-Z0-9_]{4,20}@(163|126)\.com$", "[email protected]").group(1)
'163'
>>> import re
>>> re.match(r"([a-zA-Z0-9_]{4,20})@(163|126)\.com$", "[email protected]").group(1)
'laowang'
>>> import re
>>> html_str = "hahahah
"
>>> re.match(r"<(\w*)>.*\1>", html_str).group()
'hahahah
'
>>> import re
>>> html_str = "hahahah
"
>>> re.match(r"<(\w*)><(\w*)>.*\2>\1>", html_str).group()
'hahahah
'
>>> import re
>>> re.match(r"<(?P\w*)><(?P\w*)>.*(?P=p2)>(?P=p1)>" , html_str).group()
'hahahah
'
Match()的功能是从头开始匹配,是其它语言都有的功能。
# 需求:匹配出文章阅读的次数
import re
ret = re.search(r"\d+", "阅读次数为 9999")
ret.group()
# 运行结果:
'9999'
# 需求:统计出python、c、c++相应文章阅读的次数
import re
ret = re.findall(r"\d+", "python = 9999, c = 7890, c++ = 12345")
print(ret)
# 运行结果:
['9999', '7890', '12345']
# 需求:将匹配到的阅读次数加1
# 方法1:
import re
ret = re.sub(r"\d+", '998', "python = 997")
print(ret)
# 运行结果:
python = 998
import re
def add(temp):
strNum = temp.group()
num = int(strNum) + 1
return str(num)
ret = re.sub(r"\d+", add, "python = 997")
print(ret)
ret = re.sub(r"\d+", add, "python = 99")
print(ret)
# 运行结果:
python = 998
python = 100
# 需求:切割字符串“info:xiaoZhang 33 shandong”
# 要么冒号:要么空格切割
import re
ret = re.split(r":| ","info:xiaoZhang 33 shandong")
print(ret)
# 运行结果:
['info', 'xiaoZhang', '33', 'shandong']
import re
test_str="""
职位描述:
我们希望遇到以下的您:
1、负责监控平台整体架构的设计与开发;
2、负责完成音视频、服务端的开发,完成系统框架与核心代码的实现与日常维护;
3、负责设计和开发音视频编码、实时传输、存储以及播放解决方案;
4、负责技术攻关和创新技术引用,管理整体核心技术,组织制定和实施重大技术决策和技术方案,把握技术路线及技术发展方向,制定技术发展规划。
我们希望您具备以下能力:
1、计算机相关专业,本科及以上学历,2年以上多媒体相关开发经验;
2、熟悉常用算法和数据结构,有一定的架构能力和良好代码规范;
3、熟悉音视频编解码技术H264、hevc、amr、aac、音视频封装格式mp4、flv、mkv、mp3,熟悉常用开源库ffmpeg、srs、x264、libav;
4、精通TCP、UDP等网络传输协议和互联网视频的直播及点播应用开发,熟悉RTP/RTCP/RTSP/RTMP/HLS 等流媒体协议;
5、具有较高的职业素养、敬业精神具有极强的内驱力与责任心,能够承担较大的工作压力;
6、具有优秀的管理才能和职业操守,优秀的沟通能力和领导能力,工作风格干净利落,具有战略思维和团队激励能力,有较强的执行力。
"""
ret=re.sub(r"<[^>]*>| |\n", "", test_str)
print(ret)
# 参考答案:
re.sub(r"<[^>]*>| |\n", "", test_str)
Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;非贪婪则相反,总是尝试匹配尽可能少的字符。
在"*","?","+","{m,n}"后面加上?,使贪婪变成非贪婪。
>>> s="This is a number 234-235-22-423"
>>> r=re.match(".+(\d+-\d+-\d+-\d+)",s)
>>> r.group(1)
'4-235-22-423'
>>> r=re.match(".+?(\d+-\d+-\d+-\d+)",s)
>>> r.group(1)
'234-235-22-423'
正则表达式模式中使用到通配字,那它在从左到右的顺序求值时,会尽量“抓取”满足匹配最长字符串,在我们上面的例子里面,“.+”会从字符串的起始处抓取满足模式的最长字符,其中包括我们想得到的第一个整型字段中的大部分,“\d+”只需一位字符就可以匹配,所以它匹配了数字“4”,而“.+”则匹配了从字符串起始到这个第一位数字4之前的所有字符。
解决方式:非贪婪操作符“?”,这个操作符可以用在"*" “+” "?"的后面,要求正则匹配的越少越好。
>>> re.match(r"aa(\d+)","aa2343ddd").group(1)
'2343'
>>> re.match(r"aa(\d+?)","aa2343ddd").group(1)
'2'
>>> re.match(r"aa(\d+)ddd","aa2343ddd").group(1)
'2343'
>>> re.match(r"aa(\d+?)ddd","aa2343ddd").group(1)
'2343'
练一练:请提取url地址
字符串为:
<img data-original="https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg" src="https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg" style="display: inline;">
参考答案
re.search(r"https://.*?\.jpg", test_str)
>>> mm = "c:\\a\\b\\c"
>>> mm
'c:\\a\\b\\c'
>>> print(mm)
c:\a\b\c
>>> re.match("c:\\\\",mm).group()
'c:\\'
>>> ret = re.match("c:\\\\",mm).group()
>>> print(ret)
c:\
>>> ret = re.match("c:\\\\a",mm).group()
>>> print(ret)
c:\a
>>> ret = re.match(r"c:\\a",mm).group()
>>> print(ret)
c:\a
>>> ret = re.match(r"c:\a",mm).group()
Traceback (most recent call last):
File "" , line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
说明:
Python中字符串前面加上 r 表示原生字符串,
与大多数编程语言相同,正则表达式里使用 " \ " 作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符 " \ ",那么使用编程语言表示的正则表达式里将需要4个反斜杠 " \ \ ":前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。
Python里的原生字符串很好地解决了这个问题,有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。
>>> ret = re.match(r"c:\\a",mm).group()
>>> print(ret)
c:\a