正则表达式
应用场景
特定规律字符串的查找切割替换等
邮箱格式, URL,IP 等的校验
爬虫项目中, 特定内容的提取
使用原则
只要使用字符串等函数解决的问题, 就不要使用正则
正则的效率比较低, 同时会降低代码的可读性.
世界上最难理解的三样东西: 医生的处方, 道士的神符, 码农的正则.
提醒: 正则是用来写的, 不是用来读的; 在不指定功能的情况下, 不要试图阅读别人的正则.
基本使用
说明: 正则不是我们写的, python 中正则的解析通过 re 模块完成
相关函数:
match: 从开头进行匹配, 匹配到就返回正则结果对象, 没有返回 None.
search: 从任意位置匹配, 功能同上.
- # 从开头查找, 找到返回正则匹配结果对象, 没有找到返回 None
- # m = re.match('abc', 'abcdask;jabcsdajl')
- # 从任意位置查找, 功能同上
- m = re.search('abc', 'shdalsjdabchaoeor')
- ?
- if m:
- # 返回匹配的内容
- print(m.group())
- # 返回匹配内容位置
- print(m.span())
findall: 全部匹配, 返回匹配到的内容组成的列表, 没有返回空列表.
- # 匹配所有内容, 找到返回所有匹配的内容列表, 没有找到返回空列表
- f = re.findall('abcd', 'adsjkjdabcajsdlasabcjsdlaabc')
- print(f)
compile: 生成正则表达式对象
- # 先生成正则表达式对象
- c = re.compile('hello')
- # print(type(c))
- ?
- # 从开头匹配
- m = c.match('hellosadk;ask;kahellosadhlkas')
- print(m)
- ?
- # 从任意位置匹配
- s = c.search('hadlsjasdhellokjsdlks')
- print(s)
- ?
- # 匹配所有内容
- f = c.findall('hellosdhasdjahelloshdajldhello')
- print(f)
说明: 此方式更加灵活, 将正则匹配分为两步完成(先生成正则对象, 然后需要时进行匹配)
正则规则
单个字符
普通字符: 简单来说就是一对一的完全匹配.
[]: 中间的任意一个字符
[a-z]:a~z 之间的任意字符(所有的小写字母)
[a-zA-Z]: 匹配所有的字母, 多个连续的片段中间不能有任何多余的字符
[^0-9]: 匹配除 0-9 以外的任意字符
. : 匹配除'\n'以外的任意字符
\d: 数字字符, 等价于[0-9]
\D: 非数字字符, 等价于[^0-9]
\w: 匹配字(数字, 字母, 下划线, 汉字)
\W: 匹配非字(\w 相反的内容)
\s: 所有的空白字符(\n,\t,\r, 空格)
\S: 非空白字符(\s 相反的内容)
\b: 词边界(开头, 结尾, 空格, 标点等)
\B: 非词边界(\b 相反的内容)
次数限定
*: 前面的字符出现任意次
+: 至少一次
?: 最多一次
{m,n}:m <= 次数 <= n
{m,}: 至少 m 次
{,n}: 至多 n 次
{m}: 指定 m 次
边界限定
^: 以指定的内容开头
$: 以指定的内容结束
示例:
- import re
- ?
- # ^: 以指定内容开头
- # f = re.findall('^hello', 'hellosjdhelloalskdhello')
- ?
- # $: 以指定内容结尾
- f = re.findall('hello$', 'hellosjdhelloalskdhello')
- ?
- print(f)
优先级控制
|: 表示或, 它拥有最低的优先级
(): 表示一个整体, 可以明确的指定结合性 / 优先级
示例:
- import re
- ?
- f = re.findall('a(hello|world)c', 'sahdjsahellocaworldcjsdhs')
- ?
- print(f)
分组匹配
示例 1:
- import re
- ?
- c = re.compile(r'(\d+)([a-z]+)(\d+)')
- ?
- s = c.search('sdsdj235sadhasjd36432sjdha')
- ?
- # 完整匹配结果
- print(s.group(), s.span())
- # 等价于上式
- print(s.group(0), s.span(0))
- # 第几个 () 匹配的结果
- print(s.group(1), s.span(1))
- print(s.group(2), s.span(2))
- print(s.group(3), s.span(3))
示例 2:
- import re
- ?
- # 固定匹配
- # c = re.compile(r'<a>\w+</a>')
- ?
- # \1 表示前面第一个 () 匹配的内容
- # c = re.compile(r'<([a-z]+)><([a-z]+)>\w+</\2></\1>')
- ?
- # 给分组 () 起名字
- c = re.compile(r'<(?P<goudan>[a-z]+)><(?P<dahua>[a-z]+)>\w+</(?P=dahua)></(?P=goudan)>')
- ?
- s = c.search('<div><a > 百度一下</a></div>')
- ?
- if s:
- print(s.group())
贪婪匹配
贪婪: 最大限度的匹配. 正则的匹配默认就是贪婪的.
非贪婪: 只要满足条件, 能少匹配就少匹配.'?'经常用于取消贪婪
示例:
- import re
- ?
- # ?: 取消任意多次的贪婪匹配
- # c = re.compile(r'a.*?b')
- ?
- # ?: 取消至少一次的贪婪匹配
- c = re.compile(r'a.+?b')
- ?
- s = c.search('ssjdsdabjdsd')
- ?
- if s:
- print(s.group())
匹配模式
说明: 所谓匹配模式就是对匹配的原则进行整体的修饰.
示例:
- import re
- ?
- # 忽略大小写 re.I
- s = re.search(r'hello', 'HELLO world', re.I)
- ?
- # 正则默认是单行匹配, 使用 re.M 可以进行多行匹配
- s = re.search(r'^hello', 'sdhasdh\nhello world', re.M)
- ?
- # 使. 匹配任意字符, 作为单行处理, 忽略 \ n
- # string = '<div>hello</div>'
- string = '''<div>
- hello
- </div>'''s = re.search(r'<div>.*?</div>', string, re.S)
- ?
- if s:
- print(s.group())
练习
邮箱格式的匹配
- # 邮箱格式的匹配
- import re
- c = re.compile(r'^\w+@(\w+\.)+(com|cn|edu|net)$')
- string = 'lijie@100phone.com'
- # string = 'lijie@100phone.com.cn'
- # string = 'lijie@100phone.edu'
- s = c.search(string)
- if s:
- print(s.group())
手机号码的匹配
- # 手机号码的匹配
- import re
- x = r'^(1[3578]\d{9}|147\d{8})$'
- print(re.match(x,'18768853995').group())
正则表达式
来源: http://www.bubuko.com/infodetail-2811751.html