|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 和vvv 于 2019-7-24 08:35 编辑
13 正则表达式实战
一、什么是正则表达式
世界上的数据很多,而很多时候我们需要的只是其中的一部分。此时我们可以通过一些表达式进行提取,正则表达式就是其中的一种筛选数据的表达式。还有其他的表达式,如xpath 表达式等。
二、原子
原子是正则表达式中最基本的组成单位,每个正则表达式中至少包含一个原子。常见的原子类型有:
- 普通字符作为原子
- 非打印字符作为原子
- 通用字符作为原子
- 原子表
要使用正则表达式,需导入re模块(自带模块)。
(1)普通字符做原子:- import re
- s = "titainxiangshang"
- #普通字符做原子
- pat = "ain"
- #search函数
- rst = re.search(pat,s)
- print(rst)
复制代码- >>>
- ======== RESTART: F:\Python\procedure\if.py ========
- <_sre.SRE_Match object; span=(3, 6), match='ain'>
- >>>
复制代码 如果改变pat:- import re
- s = "titainxiangshang"
- #普通字符做原子
- pat = "fain"
- #search函数
- rst = re.search(pat,s)
- print(rst)
复制代码- >>>
- ======== RESTART: F:\Python\procedure\if.py ========
- None
- >>>
复制代码 因为字符串里并没有pat里的内容。
(2)非打印字符(如"\n")作原子:- import re
- #非打印字符作原子
- #\n:换行 \t:制表符
- s = '''titainxiangshang
- baidu
- '''
- pat = "\n"
- #search函数
- rst = re.search(pat,s)
- print(rst)
复制代码- >>>
- ======== RESTART: F:\Python\procedure\if.py ========
- <_sre.SRE_Match object; span=(16, 17), match='\n'>
- >>>
复制代码 如果没有换行:- import re
- #非打印字符作原子
- #\n:换行 \t:制表符
- s = '''titainxiangshangbaidu'''
- pat = "\n"
- #search函数
- rst = re.search(pat,s)
- print(rst)
复制代码- >>>
- ======== RESTART: F:\Python\procedure\if.py ========
- None
- >>>
复制代码
(3)通用字符作为原子:- import re
- #通用字符作原子
- '''
- \w: 字匹配任意字母、数字、下划线
- \W:匹配除字母、数字、下划线以外的任意字符
- \d:十进制数
- \D:除十进制数
- \s:空白字符
- \S:除空白字符
- '''
- s = "titainx154212454iangshang"
- #匹配两位数字
- pat1 = "\d\d"
- pat2 = "\w\d\d\d"
- #search函数
- rst1 = re.search(pat1,s)
- rst2 = re.search(pat2,s)
- print(rst1)
- print(rst2)
复制代码- >>>
- ======== RESTART: F:\Python\procedure\if.py ========
- <_sre.SRE_Match object; span=(7, 9), match='15'>
- <_sre.SRE_Match object; span=(6, 10), match='x154'>
- >>>
复制代码
(4)原子表- import re
- #原子表
- #[xyz]:从表中任意提取一个字符
- s = "titainx154212454iangshang"
- pat = "s[ainh]ang"
- rst = re.search(pat,s)
- print(rst)
复制代码- >>>
- ======== RESTART: F:\Python\procedure\if.py ========
- <_sre.SRE_Match object; span=(20, 25), match='shang'>
- >>>
复制代码 如果在原子表里加上“^”,表示除了原子表内的字符,匹配其他的任意字符。- import re
- #原子表
- #[xyz]:从表中任意提取一个字符
- s = "titainx154212454iangshang"
- pat = "s[^ain]ang"
- rst = re.search(pat,s)
- print(rst)
复制代码- >>>
- ======== RESTART: F:\Python\procedure\if.py ========
- <_sre.SRE_Match object; span=(20, 25), match='shang'>
- >>>
复制代码
三、元字符
所谓元字符,就是正则表达式中具有一些特殊含义的字符,比如重复N次前面的字符等。
(1)
- import re
- s = "titainx154212454iangshang"
- pat1 = "s.ang"
- pat2 = "^s...."
- rst1 = re.search(pat1,s)
- rst2 = re.search(pat2,s)
- print(rst1)
- print(rst2)
复制代码- >>>
- ======== RESTART: F:\Python\procedure\if.py ========
- <_sre.SRE_Match object; span=(20, 25), match='shang'>
- None
- >>>
复制代码 (2)*,+,?的用法:
- import re
- s = "titainx154212454iangshang"
- pat1 = "tit*"
- pat2 = "tit+"
- pat3 = "tit?"
- rst1 = re.search(pat1,s)
- rst2 = re.search(pat2,s)
- rst3 = re.search(pat3,s)
- print(rst1)
- print(rst2)
- print(rst3)
复制代码- >>>
- ======== RESTART: F:\Python\procedure\if.py ========
- <_sre.SRE_Match object; span=(0, 3), match='tit'>
- <_sre.SRE_Match object; span=(0, 3), match='tit'>
- <_sre.SRE_Match object; span=(0, 3), match='tit'>
- >>>
复制代码 加上 . 匹配符之后:- import re
- s = "titainx154212454iangshang"
- pat1 = "tit.*"
- pat2 = "tit.+"
- pat3 = "tit.?"
- rst1 = re.search(pat1,s)
- rst2 = re.search(pat2,s)
- rst3 = re.search(pat3,s)
- print(rst1)
- print(rst2)
- print(rst3)
复制代码- >>>
- ======== RESTART: F:\Python\procedure\if.py ========
- <_sre.SRE_Match object; span=(0, 25), match='titainx154212454iangshang'>
- <_sre.SRE_Match object; span=(0, 25), match='titainx154212454iangshang'>
- <_sre.SRE_Match object; span=(0, 4), match='tita'>
- >>>
复制代码 (3){}的用法- import re
- s = "titainnnnx154212454iangshang"
- pat1 = "ain{4}"
- rst1 = re.search(pat1,s)
- print(rst1)
复制代码- >>>
- ======== RESTART: F:\Python\procedure\if.py ========
- <_sre.SRE_Match object; span=(3, 9), match='ainnnn'>
- >>>
复制代码
这几种用法的区别:
- import re
- s = "titainnnnx154212454iangshang"
- #匹配4个n
- pat1 = "ain{4}"
- #匹配5个n
- pat2 = "ain{5}"
- #匹配3个n
- pat3 = "ain{3}"
- #匹配至少3个n
- pat4 = "ain{3,}"
- rst1 = re.search(pat1,s)
- rst2 = re.search(pat2,s)
- rst3 = re.search(pat3,s)
- rst4 = re.search(pat4,s)
- print(rst1)
- print(rst2)
- print(rst3)
- print(rst4)
复制代码- >>>
- ======== RESTART: F:\Python\procedure\if.py ========
- <_sre.SRE_Match object; span=(3, 9), match='ainnnn'>
- None
- <_sre.SRE_Match object; span=(3, 8), match='ainnn'>
- <_sre.SRE_Match object; span=(3, 9), match='ainnnn'>
- >>>
复制代码
四、模式修正符
所谓的模式修正符,即可以在不改变正则表达式的情况下,通过模式修正符改变正则表达式的含义,从而实现一些匹配结果的调整等功能。
- I:匹配时忽略大小写
- M:多行匹配
- L:本地化识别匹配
- U:unicode
- S:让 . 匹配包括换行符
- import re
- string = "Python"
- pat = "pyt"
- rst = re.search(pat,string)
- print(rst)
复制代码- >>>
- ======== RESTART: F:\Python\procedure\if.py ========
- None
- >>>
复制代码 使用修正符:- import re
- string = "Python"
- pat = "pyt"
- rst = re.search(pat,string,re.I)
- print(rst)
复制代码- >>>
- ======== RESTART: F:\Python\procedure\if.py ========
- <_sre.SRE_Match object; span=(0, 3), match='Pyt'>
- >>>
复制代码
五、贪婪模式和懒惰模式
贪婪模式的核心点就是尽可能多的匹配,而懒惰模式的核心点就是尽可能少的匹配。
(1)默认是贪婪匹配- import re
- string = "Poythonyvcvbfvbf"
- pat = "p.*y"
- rst = re.search(pat,string,re.I)
- print(rst)
复制代码- >>>
- ======== RESTART: F:\Python\procedure\if.py ========
- <_sre.SRE_Match object; span=(0, 7), match='Pythony'>
- >>>
复制代码 (2)懒惰模式直接加 ?(.*?)- import re
- string = "Poythonyvcvbfvbf"
- pat = "p.*?y"
- rst = re.search(pat,string,re.I)
- print(rst)
复制代码- >>>
- ======== RESTART: F:\Python\procedure\if.py ========
- <_sre.SRE_Match object; span=(0, 3), match='Poy'>
- >>>
复制代码
贪婪模式的匹配比较模糊,懒惰模式的匹配比较精确。
六、正则表达式函数
正则表达式函数有re.match()函数、re.search()函数、全局匹配函数、re.sub()函数。正则表达式只匹配,不能实现功能,需要正则表达式函数来实现。
(1)re.match()函数:从开头开始匹配。- import re
- string = "Poythonyvcvbfvbf"
- pat = "p.*?y"
- rst = re.match(pat,string,re.I)
- print(rst)
复制代码- >>>
- ======== RESTART: F:\Python\procedure\if.py ========
- <_sre.SRE_Match object; span=(0, 3), match='Poy'>
- >>>
复制代码 可以匹配。但下列情况不行:- import re
- string = "Poythonyvcvbfvbf"
- pat = "o.*?y"
- rst = re.match(pat,string,re.I)
- print(rst)
复制代码- >>>
- ======== RESTART: F:\Python\procedure\if.py ========
- None
- >>>
复制代码
也就是说,re.match()函数只能从开头开始匹配。
(2)全局匹配函数
re.search()函数只能匹配到一个:- import re
- string = "Poythopnyvcpvbfyvpbfy"
- pat = "p.*?y"
- rst = re.search(pat,string,re.I)
- print(rst)
复制代码- >>>
- ======== RESTART: F:\Python\procedure\if.py ========
- <_sre.SRE_Match object; span=(0, 3), match='Poy'>
- >>>
复制代码 全局匹配函数全部匹配:re.compile(正则表达式).findall(数据)- import re
- string = "Poythopnyvcpvbfyvpbfy"
- pat = "p.*?y"
- rst = re.compile(pat,re.I).findall(string)
- print(rst)
复制代码- >>>
- ======== RESTART: F:\Python\procedure\if.py ========
- ['Poy', 'pny', 'pvbfy', 'pbfy']
- >>>
复制代码 (3)re.sub()替换函数:re.sub(被替换数据,要替换成的数据,数据)- import re
- string = "Poythopnyvcpvbfyvpbfy"
- rst = re.sub("p","?",string)
- print(rst)
复制代码- >>>
- ======== RESTART: F:\Python\procedure\if.py ========
- Poytho?nyvc?vbfyv?bfy
- >>>
复制代码
七、常见正则实例
(1)匹配.com和.cn
- string = "<a >百度首页</a>"
- pat = "[a-zA-Z]+://[^\s]*[.com|.cn]"
- rst = re.compile(pat).findall(string)
- print(rst)
复制代码- >>>
- ======== RESTART: F:\Python\procedure\if.py ========
- ['http://www.baidu.com']
- >>>
复制代码
(2)匹配电话号码- #匹配电话号码
- string = "ujdhnvjvbnjvbj021-454152451452xjbjb0123-52212541512"
- pat = "\d{4}-\d{7}|\d{3}-\d{8}"
- rst = re.compile(pat).findall(string)
- print(rst)
复制代码- >>>
- ======== RESTART: F:\Python\procedure\if.py ========
- ['021-45415245', '0123-5221254']
- >>>
复制代码
|
评分
-
查看全部评分
|