鱼C论坛

 找回密码
 立即注册
查看: 2436|回复: 1

[技术交流] 13 正则表达式实战

[复制链接]
发表于 2017-6-20 19:07:22 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 和vvv 于 2019-7-24 08:35 编辑
13 正则表达式实战

一、什么是正则表达式
世界上的数据很多,而很多时候我们需要的只是其中的一部分。此时我们可以通过一些表达式进行提取,正则表达式就是其中的一种筛选数据的表达式。还有其他的表达式,如xpath 表达式等。


二、原子
原子是正则表达式中最基本的组成单位,每个正则表达式中至少包含一个原子。常见的原子类型有:
  • 普通字符作为原子
  • 非打印字符作为原子
  • 通用字符作为原子
  • 原子表



要使用正则表达式,需导入re模块(自带模块)。
  1. import re
复制代码

(1)普通字符做原子:
  1. import re
  2. s = "titainxiangshang"
  3. #普通字符做原子
  4. pat = "ain"
  5. #search函数
  6. rst = re.search(pat,s)
  7. print(rst)
复制代码
  1. >>>
  2. ======== RESTART: F:\Python\procedure\if.py ========
  3. <_sre.SRE_Match object; span=(3, 6), match='ain'>
  4. >>>
复制代码
如果改变pat:
  1. import re
  2. s = "titainxiangshang"
  3. #普通字符做原子
  4. pat = "fain"
  5. #search函数
  6. rst = re.search(pat,s)
  7. print(rst)
复制代码
  1. >>>
  2. ======== RESTART: F:\Python\procedure\if.py ========
  3. None
  4. >>>
复制代码
因为字符串里并没有pat里的内容。

(2)非打印字符(如"\n")作原子:
  1. import re
  2. #非打印字符作原子
  3. #\n:换行 \t:制表符
  4. s = '''titainxiangshang
  5. baidu
  6. '''
  7. pat = "\n"
  8. #search函数
  9. rst = re.search(pat,s)
  10. print(rst)
复制代码
  1. >>>
  2. ======== RESTART: F:\Python\procedure\if.py ========
  3. <_sre.SRE_Match object; span=(16, 17), match='\n'>
  4. >>>
复制代码
如果没有换行:
  1. import re
  2. #非打印字符作原子
  3. #\n:换行 \t:制表符
  4. s = '''titainxiangshangbaidu'''
  5. pat = "\n"
  6. #search函数
  7. rst = re.search(pat,s)
  8. print(rst)
复制代码
  1. >>>
  2. ======== RESTART: F:\Python\procedure\if.py ========
  3. None
  4. >>>
复制代码

(3)通用字符作为原子:
  1. import re
  2. #通用字符作原子
  3. '''
  4. \w: 字匹配任意字母、数字、下划线
  5. \W:匹配除字母、数字、下划线以外的任意字符
  6. \d:十进制数
  7. \D:除十进制数
  8. \s:空白字符
  9. \S:除空白字符
  10. '''
  11. s = "titainx154212454iangshang"
  12. #匹配两位数字
  13. pat1 = "\d\d"
  14. pat2 = "\w\d\d\d"
  15. #search函数
  16. rst1 = re.search(pat1,s)
  17. rst2 = re.search(pat2,s)
  18. print(rst1)
  19. print(rst2)
复制代码
  1. >>>
  2. ======== RESTART: F:\Python\procedure\if.py ========
  3. <_sre.SRE_Match object; span=(7, 9), match='15'>
  4. <_sre.SRE_Match object; span=(6, 10), match='x154'>
  5. >>>
复制代码

(4)原子表
  1. import re
  2. #原子表
  3. #[xyz]:从表中任意提取一个字符
  4. s = "titainx154212454iangshang"
  5. pat = "s[ainh]ang"
  6. rst = re.search(pat,s)
  7. print(rst)
复制代码
  1. >>>
  2. ======== RESTART: F:\Python\procedure\if.py ========
  3. <_sre.SRE_Match object; span=(20, 25), match='shang'>
  4. >>>
复制代码
如果在原子表里加上“^”,表示除了原子表内的字符,匹配其他的任意字符。
  1. import re
  2. #原子表
  3. #[xyz]:从表中任意提取一个字符
  4. s = "titainx154212454iangshang"
  5. pat = "s[^ain]ang"
  6. rst = re.search(pat,s)
  7. print(rst)
复制代码
  1. >>>
  2. ======== RESTART: F:\Python\procedure\if.py ========
  3. <_sre.SRE_Match object; span=(20, 25), match='shang'>
  4. >>>
复制代码



三、元字符
所谓元字符,就是正则表达式中具有一些特殊含义的字符,比如重复N次前面的字符等。
  • .  :匹配除换行符以外的任意一个字符


  • ^ :不在原子表里,表示匹配开始位置


  • $ :匹配结束位置


  • * :前面元素重复出现0次或1次或多次


  • ? :前面元素重复出现0次或1次


  • + :前面元素重复出现1次或多次


  • {n} :前面元素恰好出现n次


  • {n,} :前面元素至少出现n次


  • {n,m} :前面元素至少出现n次,至多出现m次


  • |:模式选择符或


  • () :模式单元


(1)

  1. import re
  2. s = "titainx154212454iangshang"
  3. pat1 = "s.ang"
  4. pat2 = "^s...."
  5. rst1 = re.search(pat1,s)
  6. rst2 = re.search(pat2,s)
  7. print(rst1)
  8. print(rst2)
复制代码
  1. >>>
  2. ======== RESTART: F:\Python\procedure\if.py ========
  3. <_sre.SRE_Match object; span=(20, 25), match='shang'>
  4. None
  5. >>>
复制代码
(2)*,+,?的用法:
  1. import re
  2. s = "titainx154212454iangshang"
  3. pat1 = "tit*"
  4. pat2 = "tit+"
  5. pat3 = "tit?"
  6. rst1 = re.search(pat1,s)
  7. rst2 = re.search(pat2,s)
  8. rst3 = re.search(pat3,s)
  9. print(rst1)
  10. print(rst2)
  11. print(rst3)
复制代码
  1. >>>
  2. ======== RESTART: F:\Python\procedure\if.py ========
  3. <_sre.SRE_Match object; span=(0, 3), match='tit'>
  4. <_sre.SRE_Match object; span=(0, 3), match='tit'>
  5. <_sre.SRE_Match object; span=(0, 3), match='tit'>
  6. >>>
复制代码
加上 . 匹配符之后:
  1. import re
  2. s = "titainx154212454iangshang"
  3. pat1 = "tit.*"
  4. pat2 = "tit.+"
  5. pat3 = "tit.?"
  6. rst1 = re.search(pat1,s)
  7. rst2 = re.search(pat2,s)
  8. rst3 = re.search(pat3,s)
  9. print(rst1)
  10. print(rst2)
  11. print(rst3)
复制代码
  1. >>>
  2. ======== RESTART: F:\Python\procedure\if.py ========
  3. <_sre.SRE_Match object; span=(0, 25), match='titainx154212454iangshang'>
  4. <_sre.SRE_Match object; span=(0, 25), match='titainx154212454iangshang'>
  5. <_sre.SRE_Match object; span=(0, 4), match='tita'>
  6. >>>
复制代码
(3){}的用法
  1. import re
  2. s = "titainnnnx154212454iangshang"
  3. pat1 = "ain{4}"
  4. rst1 = re.search(pat1,s)
  5. print(rst1)
复制代码
  1. >>>
  2. ======== RESTART: F:\Python\procedure\if.py ========
  3. <_sre.SRE_Match object; span=(3, 9), match='ainnnn'>
  4. >>>
复制代码

这几种用法的区别:
  1. import re
  2. s = "titainnnnx154212454iangshang"
  3. #匹配4个n
  4. pat1 = "ain{4}"
  5. #匹配5个n
  6. pat2 = "ain{5}"
  7. #匹配3个n
  8. pat3 = "ain{3}"
  9. #匹配至少3个n
  10. pat4 = "ain{3,}"
  11. rst1 = re.search(pat1,s)
  12. rst2 = re.search(pat2,s)
  13. rst3 = re.search(pat3,s)
  14. rst4 = re.search(pat4,s)
  15. print(rst1)
  16. print(rst2)
  17. print(rst3)
  18. print(rst4)
复制代码
  1. >>>
  2. ======== RESTART: F:\Python\procedure\if.py ========
  3. <_sre.SRE_Match object; span=(3, 9), match='ainnnn'>
  4. None
  5. <_sre.SRE_Match object; span=(3, 8), match='ainnn'>
  6. <_sre.SRE_Match object; span=(3, 9), match='ainnnn'>
  7. >>>
复制代码



四、模式修正符
所谓的模式修正符,即可以在不改变正则表达式的情况下,通过模式修正符改变正则表达式的含义,从而实现一些匹配结果的调整等功能。
  • I:匹配时忽略大小写
  • M:多行匹配
  • L:本地化识别匹配
  • U:unicode
  • S:让 . 匹配包括换行符


  1. import re
  2. string = "Python"
  3. pat = "pyt"
  4. rst = re.search(pat,string)
  5. print(rst)
复制代码
  1. >>>
  2. ======== RESTART: F:\Python\procedure\if.py ========
  3. None
  4. >>>
复制代码
使用修正符:
  1. import re
  2. string = "Python"
  3. pat = "pyt"
  4. rst = re.search(pat,string,re.I)
  5. print(rst)
复制代码
  1. >>>
  2. ======== RESTART: F:\Python\procedure\if.py ========
  3. <_sre.SRE_Match object; span=(0, 3), match='Pyt'>
  4. >>>
复制代码



五、贪婪模式和懒惰模式
贪婪模式的核心点就是尽可能多的匹配,而懒惰模式的核心点就是尽可能少的匹配。
(1)默认是贪婪匹配
  1. import re
  2. string = "Poythonyvcvbfvbf"
  3. pat = "p.*y"
  4. rst = re.search(pat,string,re.I)
  5. print(rst)
复制代码
  1. >>>
  2. ======== RESTART: F:\Python\procedure\if.py ========
  3. <_sre.SRE_Match object; span=(0, 7), match='Pythony'>
  4. >>>
复制代码
(2)懒惰模式直接加 ?(.*?)
  1. import re
  2. string = "Poythonyvcvbfvbf"
  3. pat = "p.*?y"
  4. rst = re.search(pat,string,re.I)
  5. print(rst)
复制代码
  1. >>>
  2. ======== RESTART: F:\Python\procedure\if.py ========
  3. <_sre.SRE_Match object; span=(0, 3), match='Poy'>
  4. >>>
复制代码


贪婪模式的匹配比较模糊,懒惰模式的匹配比较精确。


六、正则表达式函数
正则表达式函数有re.match()函数re.search()函数全局匹配函数re.sub()函数。正则表达式只匹配,不能实现功能,需要正则表达式函数来实现。


(1)re.match()函数:从开头开始匹配。
  1. import re
  2. string = "Poythonyvcvbfvbf"
  3. pat = "p.*?y"
  4. rst = re.match(pat,string,re.I)
  5. print(rst)
复制代码
  1. >>>
  2. ======== RESTART: F:\Python\procedure\if.py ========
  3. <_sre.SRE_Match object; span=(0, 3), match='Poy'>
  4. >>>
复制代码
可以匹配。但下列情况不行:
  1. import re
  2. string = "Poythonyvcvbfvbf"
  3. pat = "o.*?y"
  4. rst = re.match(pat,string,re.I)
  5. print(rst)
复制代码
  1. >>>
  2. ======== RESTART: F:\Python\procedure\if.py ========
  3. None
  4. >>>
复制代码

也就是说,re.match()函数只能从开头开始匹配。

(2)全局匹配函数
re.search()函数只能匹配到一个:
  1. import re
  2. string = "Poythopnyvcpvbfyvpbfy"
  3. pat = "p.*?y"
  4. rst = re.search(pat,string,re.I)
  5. print(rst)
复制代码
  1. >>>
  2. ======== RESTART: F:\Python\procedure\if.py ========
  3. <_sre.SRE_Match object; span=(0, 3), match='Poy'>
  4. >>>
复制代码
全局匹配函数全部匹配:re.compile(正则表达式).findall(数据)
  1. import re
  2. string = "Poythopnyvcpvbfyvpbfy"
  3. pat = "p.*?y"
  4. rst = re.compile(pat,re.I).findall(string)
  5. print(rst)
复制代码
  1. >>>
  2. ======== RESTART: F:\Python\procedure\if.py ========
  3. ['Poy', 'pny', 'pvbfy', 'pbfy']
  4. >>>
复制代码
(3)re.sub()替换函数:re.sub(被替换数据,要替换成的数据,数据)
  1. import re
  2. string = "Poythopnyvcpvbfyvpbfy"
  3. rst = re.sub("p","?",string)
  4. print(rst)
复制代码
  1. >>>
  2. ======== RESTART: F:\Python\procedure\if.py ========
  3. Poytho?nyvc?vbfyv?bfy
  4. >>>
复制代码



七、常见正则实例
(1)匹配.com和.cn     
  1. string = "<a >百度首页</a>"
  2. pat = "[a-zA-Z]+://[^\s]*[.com|.cn]"
  3. rst = re.compile(pat).findall(string)
  4. print(rst)
复制代码
  1. >>>
  2. ======== RESTART: F:\Python\procedure\if.py ========
  3. ['http://www.baidu.com']
  4. >>>
复制代码

(2)匹配电话号码
  1. #匹配电话号码
  2. string = "ujdhnvjvbnjvbj021-454152451452xjbjb0123-52212541512"
  3. pat = "\d{4}-\d{7}|\d{3}-\d{8}"
  4. rst = re.compile(pat).findall(string)
  5. print(rst)
复制代码
  1. >>>
  2. ======== RESTART: F:\Python\procedure\if.py ========
  3. ['021-45415245', '0123-5221254']
  4. >>>
复制代码




评分

参与人数 1鱼币 +8 收起 理由
小甲鱼 + 8 支持楼主!

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-7-11 10:50:09 | 显示全部楼层
\W:除十进制数 改成 \D
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-27 08:24

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表