说明
《Python 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
re 模块提供与Perl中类似的正则表达式匹配操作,它支持8位和Unicode字符串。正则表达式可以包含特殊字符和普通字符。
正则表达式(regular expression)是用一种形式化语法描述的文本匹配模式。模式会被解释为一组指令,然后执行这些指令并提供一个字符串作为输入,将生成一个匹配子集或者生成原字符串的一个修改版本。
"正则表达式"在讨论中经常简写为"regex"或regexp"。表达式可以包含字面量文本匹配、重复、模式组合、分支和其他复杂的规则。与创建一个特定用途的词法分析器和解析器相比,利用正则表达式,很多解析问题可以更容易地得到解决。
正则表达式通常用于涉及大量文本处理的应用中。
最普通的字符,例如“ A”,“ a”或“ 0”,是最简单的常用表达; 他们只是匹配自己,可以连接普通字符,因此last与字符串'last'匹配:
import re
re.findall('last', 'my last name')
# ['last']
re.match('last', 'last name').group(0)
# 'last'
如果想按照一定规则进行规则可就需要特殊字符的匹配语法。
正则表达式语法详解可访问「正则表达式语法」,常用的正式表达式语法:
. 匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线或汉字
\s 匹配任意的空白符
\d 匹配数字
\b 匹配单词的开始或结束
^ 匹配字符串的开始
$ 匹配字符串的结束
\W 匹配任意不是字母,数字,下划线,汉字的字符
\S 匹配任意不是空白符的字符
\D 匹配任意非数字的字符
\B 匹配不是单词开头或结束的位置
[^x] 匹配除了x以外的任意字符
[^aeiou] 匹配除了aeiou这几个字母以外的任意字符
限定符:
*重复零次或更多次
+重复一次或更多次
?重复零次或一次
{n}重复n次
{n,}重复n次或更多次
{n,m}重复n到m次
命名组:
命名组:(?P<name>.....)
前向界定 (?<=…)
后向界定 (?=…)
前向非界定 (?<!....)
后向非界定 (?!.....)
re.Pattern
是正则表达式对象,也称正则对象,re.compile(pattern, flags=0)
将字符串 pattern 编译为一个正则对象:
p = re.compile(r'(\D)(\D)(\D+)', flags=re.A)
p
# re.compile(r'(\D)(\D)(\D+)', re.IGNORECASE|re.UNICODE)
type(p)
# re.Pattern
其中 flags 参数可以传入一个或者多个(用|隔开)标志信息,在 re 模块的很多函数都支持,传入 re 常量(下文有介绍),用于扩展丰富正则表达式的匹配功能。
然后再用正则对象的各种方法中传入字符串进行匹配,会产生一个匹配对象 re.Match
:
m = p.match('abCC123')
m
# <re.Match object; span=(0, 4), match='abCC'>
type(m)
# re.Match
re 下的匹配方法也会产生匹配对象:
re.match(r'(\D)(\D)(\D+)', 'abCC123')
# <re.Match object; span=(0, 4), match='abCC'>
re.findall(r'(\D)(\D)(\D+)', 'abCC123')
# [('a', 'b', 'CC')]
因此,下边两种形式效果是相同的:
prog = re.compile(pattern)
result = prog.match(string)
# 同下
result = re.match(pattern, string)
如果需要多次使用这个正则表达式的话,使用 re.compile() 和保存这个正则对象以便复用,可以让程序更加高效。
正则对象:
# 创建正则对象
p = re.compile(r"(?P<letter>\D+)(?P<number>\d+)")
# 返回匹配对象
p.match('abCd123e')
# <re.Match object; span=(0, 7), match='abCd123'>
# 检索到第一个匹配的位置
p.search('abCd123eF234ghe')
# <re.Match object; span=(0, 7), match='abCd123'>
# 全部匹配
p.findall('abCd123e') # [('abCd', '123')]
# 迭代器,见正文 re.finditer()
p.finditer('abCd123e')
# <callable_iterator at 0x7fb1a94829a0>
# 按表达式分组拆分
p.split('abCd123e')
# ['', 'abCd', '123', 'e']
# 替换,见下文 re.sub
p.sub('0', 'abCd123e') # '0e'
p.subn('0', 'abCd123e') # ('0e', 1)
# 传递给compile()字符数包含隐式的
p.flags # 32
# 全部匹配
p.fullmatch('abCd123e') # None
p.fullmatch('abCd123') # <re.Match object ...>
# 分组的索引
p.groupindex['number']
# mappingproxy({'letter': 1, 'number': 2})
p.groupindex['number'] # 2
# 分组数
p.groups # 2
# 表达式字符串
p.pattern
# '(?P<letter>\\D+)(?P<number>\\d+)'
# SRE_Scanner 对象
p.scanner('abCd123e')
# <_sre.SRE_Scanner at 0x7fb1a944e3f0>
匹配对象:
p = re.compile(r"(?P<letter>\D+)(?P<number>\d+)")
m = p.match('abCd123e') # 生成一个匹配对象
m # <re.Match object; span=(0, 7), match='abCd123'>
# 匹配内容的头尾位置
m.start() # 0 未匹配返回 -1
m.end() # 7 未匹配返回 -1
# 匹配时传入的两个参数值
m.pos # 0
m.endpos # 8
# 对 template 进行反斜杠转义替换并且返回
# m.expand(template=...)
# 返回一个或者多个匹配的子组
m.group() # 'abCd123'
m.group(0) # 'abCd123'
m.group(1) # 'abCd'
m.group(2) # '123'
# m.group(3) # ndexError: no such group
m.group(1,2) # ('abCd', '123')
m.group(0,2) # ('abCd123', '123')
m.group('number') # '123'
m[2] # '123'
# 返回字典格式分组信息
# 支持default参数用于不参与匹配的组合
m.groupdict()
# {'letter': 'abCd', 'number': '123'}
# 最后一个匹配组名和索引值
m.lastgroup # 'number'
m.lastindex # 2
# 返回产生这个实例的正则对象
m.re
# re.compile(r'(?P<letter>\D+...)
# 匹配情况索引元组
m.regs
# ((0, 7), (0, 4), (4, 7))
# 匹配范围索引元组
m.span() # (0, 7)
# 匹配字符串
m.string # 'abCd123e'
以下是 re 模块的一此函数,这些函数会将指定字符按正则表达式进行匹配并返回指定类型的数据:
# 匹配内容的列表
re.findall(r'\d', '123a', flags=0) # ['1', '2', '3']
# 返回一个迭代器,每个元素为 匹配对象
re.finditer(r'\d', '123a', flags=0)
# <callable_iterator at 0x7fb1a80ced00>
for i in re.finditer(r'\d', '123a', flags=0):
print(i)
'''
<re.Match object; span=(0, 1), match='1'>
<re.Match object; span=(1, 2), match='2'>
<re.Match object; span=(2, 3), match='3'>
'''
# 返回一个匹配对象 re.Match
re.match(r'\d+', '123abc', flags=0)
# <re.Match object; span=(0, 3), match='123'>
# 设定次数,用正则替换字符串中的内容
re.sub(r'\D', '2', '1a3a', count=1, flags=0)
# '123a'
# 替换内容可以是一个函数,传入参数为每次匹配对象
# 将数字替换为星号
def my_repl(matchobj):
return '*' * matchobj.group(0).__len__()
re.sub(r'\d+', my_repl, '1a3a567')
# '*a*a***'
# 同 re.sub 返回一个元组 (字符串, 替换次数)
re.subn(r'\d+', '0', '1a3a567', count=0, flags=0)
# ('0a0a0', 3)
# 找到第一个匹配内容并返回 re.Match
re.search(r'\d+', 'a123bc45', flags=0)
# <re.Match object; span=(1, 4), match='123'>
# 用匹配上的内容进行分拆,返回分拆结果列表
re.split(r'\d+', 'a123bc45', maxsplit=0, flags=0)
# ['a', 'bc', '']
# 转义 pattern 中的特殊字符
re.escape(r'https://www.gairuo.com')
# 'https://www\\.gairuo\\.com'
# 是否完全匹配,None or re.Match
re.fullmatch(r'\d+', '123')
# <re.Match object; span=(0, 3), match='123'>
# 编译模板模式,返回pattern对象
re.template('\d')
# re.compile(r'\d', re.TEMPLATE|re.UNICODE)
# 清除正则表达式的缓存
re.purge()
re.A 之类的常量用于扩展丰富正则表达式的匹配功能,常用的有:
exception re.error(msg, pattern=None, pos=None)
raise 一个错误, 当传递到函数的字符串不是一个有效正则表达式的时候(比如,包含一个不匹配的括号)或者其他错误在编译时或匹配时产生。如果字符串不包含样式匹配,是不会被视为错误的。错误实例有以下附加属性:
邮箱:
规则:包含大小写字母,下划线,阿拉伯数字,点号,中划线
表达式:[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(?:\.[a-zA-Z0-9_-]+)
身份证号:
规则:xxxxxx yyyy MM dd 375 0 十八位
[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]
国内手机号码:
规则:手机号都为11位,且以1开头,第二位一般为3、5、6、7、8、9 ,剩下八位任意数字
表达式:1(3|4|5|6|7|8|9)\d{9}
国内固定电话:
规则:区号3~4位,号码7~8位
表达式:\d{3}-\d{8}|\d{4}-\d{7}
网址:
表达式:
(?:(?:http:\/\/)|(?:https:\/\/))?(?:[\w](?:[\w\-]{0,61}[\w])?\.)+[a-zA-Z]{2,6}(?:\/)
IPv4 地址:
规则:IP地址的长度为32位(共有2^32个IP地址),分为4段,每段8位,用十进制数字表示,每段数字范围为0~255,段与段之间用句点隔开
表达式:((?:(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d))
日期:
常见日期格式:yyyyMMdd、yyyy-MM-dd、yyyy/MM/dd、yyyy.MM.dd
表达式:\d{4}(?:-|\/|.)\d{1,2}(?:-|\/|.)\d{1,2}
密码:
密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线)
表达式:[a-zA-Z]\w{5,17}
强密码:
以字母开头,必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间
表达式:[a-zA-Z](?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}
中文字符:
规则:中文字符在指定 unicode 段
表达式:[\u4e00-\u9fa5]
数字:
'''
验证数字 ^[0-9]*$
验证n位的数字:^\d{n}$
验证至少n位数字:^\d{n,}$
验证m-n位的数字:^\d{m,n}$
验证零和非零开头的数字:^(0|[1-9][0-9]*)$
验证有两位小数的正实数:^[0-9]+(.[0-9]{2})?$
验证有1-3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$
验证非零的正整数:^\+?[1-9][0-9]*$
验证非零的负整数:^\-[1-9][0-9]*$
验证非负整数(正整数 + 0) ^\d+$
验证非正整数(负整数 + 0) ^((-\d+)|(0+))$
整数:^-?\d+$
非负浮点数(正浮点数 + 0):^\d+(\.\d+)?$
正浮点数 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
非正浮点数(负浮点数 + 0) ^((-\d+(\.\d+)?)|(0+(\.0+)?))$
负浮点数 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
浮点数 ^(-?\d+)(\.\d+)?$
'''
字符串:
'''
英文和数字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
长度为3-20的所有字符:^.{3,20}$
由26个英文字母组成的字符串:^[A-Za-z]+$
由26个大写英文字母组成的字符串:^[A-Z]+$
由26个小写英文字母组成的字符串:^[a-z]+$
由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$
中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$
中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
可以输入含有^%&',;=?$\”等字符:`[^%&',;=?$\x22]+`
禁止输入含有~的字符:[^~\x22]+
'''
更新时间:2020-12-22 12:42:04 标签:python 内置库 正则