正则表达式

正则表达式参考链接1
正则表达式参考链接2

一、概述

1. 概念

1.1 Regular Expression 一种文本模式,描述在搜索文本时要匹配的一个或多个字符串
1.2 典型场景
  • 数据验证
  • 文本扫描
  • 文本提取
  • 文本替换
  • 文本分割
1.3 语法
  • 字面值
     普通字符
     需转义 ,^,$,…
  • 元字符
1.4 匹配
  • 单字,预定义的元字符
     .除\n的所有字符
     \d 数字,等同于[0~9]
     \D 非数字,等同于^[0~9]
     \s 空白字符 \t\n\r\f\v
     \S 非空白字符 ^ [\t\n\r\f\v]
     \w 字母数字字符[A - Z a - z 0 - 9_]
     \W 非字母数字 ^ [A - Z a - z 0 - 9 _]
  • 批量备选
     | yes | no
  • 量词(字符、元字符,字符集如何重复)
    0或1次
    * 0或多次
    +1或多次
  • 特定
    {m, n}范围次数 {n} n次
    {m, } 至少m次
    {, n} 至多n次
  • 贪婪与非贪婪
     贪婪(默认):尽量匹配最大范围结果
     非贪婪 尽量匹配最小范围结果
     方法:量词后追加?
    例:??,* ?,+?
  • 边界匹配
     ^ 行首
     $ 行尾
     \b 单词边界
     \B 非单词边界
     \A 输入开头
     \Z 输入结尾
     注:或因上下文差异,有不同表现

二、python正则

1. 模块

import re

2. 正则对象

2.1 表现编译后的的正则表达式(编译为字节码并缓存)
2.2 编译 re.compile(r'模式')
2.3 .findall()
 查找所有非重叠匹配项
 返回list

import re
text = '32 students are in class A205.'
pattern = re.compile('\d+')# 数字匹配模板
print(pattern.findall(text))

['32', '205']

2.4 .match(string[,pos[,endpos]])
 匹配,从起始位置
 返回MatchObject

import re
text = '32 students are in class A205.'
pattern = re.compile('\d+')# 数字匹配模板
print(pattern.match(text))

输出

<_sre.SRE_Match object; span=(0, 2), match='32'>

span表示匹配的区间,区间是左开右闭的。span=(0,2),匹配的区间是[0,2)
2.5 .search(string[,pos[,endpos]])
 任意位置开始搜索,返回第一个匹配目标
 返回MatchObject

import re
text = 'There are 32 students in class A205.'
pattern = re.compile('\d+')# 数字匹配模板
print(pattern.search(text))

输出

<_sre.SRE_Match object; span=(10, 12), match='32'>

2.6 .finditer()
 查找所有匹配项
 返回包括MatchObject元素的迭代器

import re
text = 'There are 32 students in class A205.'
pattern = re.compile('\d+')# 数字匹配模板
it = pattern.finditer(text)
print(it)
for i in it:
    print(i,'*****',i.start())
for i in it:
    print(i.start())

  • 迭代对象,迭代完成后,再次遍历,迭代器内无内容
  • MatchObject.start()输出起始位置
<callable_iterator object at 0x0000000002AB5208>
<_sre.SRE_Match object; span=(10, 12), match='32'> ***** 10
<_sre.SRE_Match object; span=(32, 35), match='205'> ***** 32

三、MatchObject 匹配对象

  1. 表现被匹配的模式
  2. .group()
     参数为0或空,返回整个匹配
     有参数时返回特定分组匹配细节
     参数也可以是分组名称
  3. .groups()
     返回包含所有分组的元组
  4. .start() 返回特定分组的起始位置,参数是分组名
  5. .end() 返回特定分组的其实位置,参数是分组名
  6. .span() 返回特定分组的起止索引元组
  7. .groupiter() 以字典形式返回分组及结果
import re
text = 'There are 32 students in class A 205.'
pattern = re.compile('(\d+).*?(\d+)')# 分组数字匹配模板
p = pattern.search(text)
print('匹配结果的MatchObject对象:',p)
print('第二个分组的匹配结果:',p.group(2))
print('第二个分组的起始位置:',p.start(2))
print('第二个分组的终点位置:',p.end(2))
print('第二个分组的跨度,左开右闭:',p.span(2))
print('所有匹配的结果,返回tuple',p.groups())
匹配结果的MatchObject对象: <_sre.SRE_Match object; span=(10, 36), match='32 students in class A 205'>
第二个分组的匹配结果: 205
第二个分组的起始位置: 33
第二个分组的终点位置: 36
第二个分组的终点位置: (33, 36)
37
('32', '205')

四、Group分组

1. 场景

要分组,需要将分组对象用括号括起来

  • 从匹配模式中提取信息
  • 创建子正则
import re
text= 'dbbcdbdbdbc'
r1 = re.search(r'db+c',text)
r2 = re.search(r'(db)+c',text)
print(r1)
print(r2)

r1匹配多个b
r2匹配多个db
加括号后,可以将括号内的内容,看成一个整体
输出

<_sre.SRE_Match object; span=(0, 4), match='dbbc'>
<_sre.SRE_Match object; span=(4, 11), match='dbdbdbc'>
  • 限制备选项范围
import re
text1 = 'color'
text2 = 'colour'
pattern = re.compile('colo(r|ur)')
result1 = re.search(pattern,text1)
result2 = re.search(pattern,text2)
print('result1',result1)
print('result2',result2)

输出

result1 <_sre.SRE_Match object; span=(0, 5), match='color'>
result2 <_sre.SRE_Match object; span=(0, 6), match='colour'>
  • 重用正则模式中提取的内容
    r'(\w+)(\1)'\1重复\w匹配到的内容,一模一样的内容
import re
text = 'abcabcdef'
pattern = re.compile(r'(\w+)(\1)')
result = re.search(pattern,text)
print(result)

在满足匹配成功的情况下,第一个分组匹配尽量多的字符。

r = re.search(r'(\w+)(\w+)','hello world')
r.groups()
Out[16]: ('hell', 'o')

2.声明

(模式)
(?P<name>模式)
待匹配的对象是字符串

3.引用

  • 匹配对象内 m.group(name)
  • 通过名称访问
import re
item = "Tom:98"
pattern = re.compile(r'(?P<name>\w+):(?P<score>\d+)')
result = re.search(pattern,item)
print(result)
print('名称匹配,name',result.group('name'))
print(result.group(1))
print('名称匹配,分数',result.group('score'))
print(result.group(2))

输出

<_sre.SRE_Match object; span=(0, 6), match='Tom:98'>
名称匹配,name Tom
Tom
名称匹配,分数 98
98

五、应用

1. 字符串操作

参数使用通配符
.split(string,maxsplit=0) 分割字符串

import re
text = 'How many loved your moments of glad grace\n' \
       'And loved your beauty with love false or true\n' \
       'But one man loved the pilgrim Soul in you\n' \
       'And loved the sorrows of your changing face'
print("原文:\n",text)
# 以换行符为分割对象
result1 = re.split(r'\n',text)
print('以换行符为分割对象:\n',result1)
# 最多分割一次
result2 = re.split(r'\n',text,maxsplit=1)
print('最多分割一次:\n',result2)
# 以所有空格符(空格 换行。。。)为分割字符串
result3 = re.split(r'\W',text)
print('以所有空格符(空格 换行。。。)为分割字符串:\n',result3)
# 以“-”为分割符,并保存“-”
result4 = re.split(r'(-)','Good-morning')
print('以“-”为分割符,并保存“-”:\n',result4)

输出

原文:
 How many loved your moments of glad grace
And loved your beauty with love false or true
But one man loved the pilgrim Soul in you
And loved the sorrows of your changing face
以换行符为分割对象:
 ['How many loved your moments of glad grace', 'And loved your beauty with love false or true', 'But one man loved the pilgrim Soul in you', 'And loved the sorrows of your changing face']
最多分割一次:
 ['How many loved your moments of glad grace', 'And loved your beauty with love false or true\nBut one man loved the pilgrim Soul in you\nAnd loved the sorrows of your changing face']
以所有空格符(空格 换行。。。)为分割字符串:
 ['How', 'many', 'loved', 'your', 'moments', 'of', 'glad', 'grace', 'And', 'loved', 'your', 'beauty', 'with', 'love', 'false', 'or', 'true', 'But', 'one', 'man', 'loved', 'the', 'pilgrim', 'Soul', 'in', 'you', 'And', 'loved', 'the', 'sorrows', 'of', 'your', 'changing', 'face']
以“-”为分割符,并保存“-”:
 ['Good', '-', 'morning']

.sub(repl,string,count=0) 替换字符串

  • markdown版的加粗改为html版加粗
import re
#内部引用
text = 'Beautiful is *better* than ugly.'
pattern = re.compile(r'\*(.*?)\*')
# markdown版的加粗改为html版加粗
# \g<1>引用内部分组的内容,索引引用
result2 = re.sub(pattern,'<strong>\g<1></strong>',text)
print('原文-markdown版:\n',text)
print("索引引用-html版:\n",result2)
pattern2 = re.compile(r'\*(?P<html>.*?)\*')
# \g<html>引用内部分组的内容,名称引用
result3 = re.sub(pattern2,'<strong>\g<html></strong>',text)
print("名称引用-html版:\n",result3)

输出

原文-markdown版:
 Beautiful is *better* than ugly.
索引引用-html版:
 Beautiful is <strong>better</strong> than ugly.
名称引用-html版:
 Beautiful is <strong>better</strong> than ugly.
  • .subn(repl,string,count=0) 替换并返回替换数量
import re
ords='ord000-ord001-ord002'
# re.sub(匹配项,替换符,原字符串)
# ?替换数字
result1 = re.sub(r'\d+','?',ords)
# r'([A-Z]+)(\d+)'看成一个整体,用'\g<2>\g<1>'这个整体代替
result2 = re.sub(r'([A-Z]+)(\d+)','\g<2>\g<1>',ords)
print('原始字符串:\n',ords)
print('?替换-:\n',result1)
print('内部引用-替换:\n',result2)

输出

原始字符串:
 ord000-ord001-ord002
?替换-:
 ord?-ord?-ord?
内部引用-替换:
 ord000-ord001-ord002
2.编译标记

改变正则的默认行为

  • re.I 忽略大小写
import re
text = 'python Python PYTHON'
result1 = re.findall(r'python',text)
result2 = re.findall(r'python',text,re.I)
print('默认情况:\n',result1)
print('忽略大小写:\n',result2)

输出

默认情况:
 ['python']
忽略大小写:
 ['python', 'Python', 'PYTHON']
  • re.M 匹配多行
import re
text = '\npython'
result1 = re.findall(r'^python',text)
result2 = re.findall(r'^python',text,re.M)
print('默认情况:\n',result1)
print('匹配所有行:\n',result2)

输出

默认情况:
 []
匹配所有行:
 ['python']
  • re.S 指定“.”匹配所有字符,包括\n
import re
text = 'python\n'
result1 = re.findall(r'.',text)
result2 = re.findall(r'.',text,re.S)
print('默认情况:\n',result1)
print('匹配所有字符(包括换行):\n',result2)

输出

默认情况:
 ['p', 'y', 't', 'h', 'o', 'n']
匹配所有字符(包括换行):
 ['p', 'y', 't', 'h', 'o', 'n', '\n']
3.模块级别操作

re.purge() 清理正则缓存
re.escape() 逃逸字符 不考虑字符的的特殊含义,比如^、$等

import re
text = '^python^\n'
result1 = re.findall(r'^',text)
result2 = re.findall(re.escape('^'),text)
print('默认情况:\n',result1)
print('忽略通配符意义:\n',result2)

输出

默认情况:
 ['']
忽略通配符意义:
 ['^', '^']
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值