正则表达式模块 (re) 内容
re 模块是 python 的一个库, 里面有很多方法可以对正则表达式进行运用.
re.search(pattern,string,flags = 0)
参数 | 描述 |
---|---|
pattern | 正则表达式 |
string | 要匹配的字符串 |
flags | 标志值,用于改变正则表达式的行为 |
flags 有哪些值:
标志 | 含义 |
---|---|
re.S(DOTALL) | 使. 匹配包括换行在内的所有字符 |
re.I(IGNORECASE) | 使匹配对大小写不敏感 |
re.L(LOCALE) | 做本地化识别(locale-aware) 匹配,法语等 |
re.M(MULTILINE) | 多行匹配,影响 ^ 和 $ |
re.X(VERBOSE) | 该标志通过给予更灵活的格式以便将正则表达式写得更易于理解 |
re.U(UNICODE) | 根据 Unicode 字符集解析字符。在 python3 是多余的, python3 默认使用 Unicode 字符串 |
re.A(ASCII) | 使 \ w, \W,\b, \B,\d, \D,\s 和 \S 只执行 ASCII 匹配而不完全是 Unicode 匹配。 |
注: 下面方法中的同名参数和上述介绍的参数意思一样, 将不再过多的解释.
作用: 从左到右扫描整个字符串 返回第一个与正则表达式匹配的对象, 如果没有匹配成功就返回 None
比如: 查找 字符串中 CodeId 第一次出现的位置
1import re2text = 'Welcome to CodeId. CodeId'3result = re.search(r'CodeId',text)4print(result.start())5# 结果为: 11
注: 返回的 result 为匹配对象, 其中 result.start()是返回开始匹配的位置索引. 由此我们可以猜到 result.end()应该是返回匹配结束时的位置索引.
re.match(pattern,string,flags = 0 )
作用: 查找字符串开头的零个或几个字符是否与正则表达式匹配, 如果成功则返回相应的匹配对象, 否则返回 None
比如: 判断 python 变量 的开头是否是数字.
1result = re.match(r'\d+','123CodeId')2if result :3 print("python 变量 的开头含有数字")4# 结果为: python 变量 的开头含有数字
注意: re.match()只会匹配字符串的开头, 即使在 MULTILINE(多行)模式下, 也不会匹配每行的开头.
- 1result = re.match(r'a','b\na',re.MULTILINE)2print(result)3# 结果为: None4# 证明匹配失败
- re.fullmatch(pattern,string,flags = 0 )
作用: 如果整个字符串都与正则表达式匹配, 则返回相应的匹配对象, 否则返回 None
比如: 判断输入的邮箱是否合法
1# 判断输入的邮箱是否合法 2email = '12323123@qq.com'3result = re.fullmatch(r'^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$',email)4if result :5 print("你输入的邮箱:",result.group(),"是合法的")6# 结果为: 你输入的邮箱: 12323123@qq.com 是合法的
注: result.group()是匹配对象的一个方法, 作用是: 返回匹配的所有子串. 后面会进行详细介绍.
re.split(pattern,string,maxsplit = 0,flags = 0 )
作用: 以字符串中与正则表达式匹配的子串, 为分隔符, 对字符串进行分割. 返回分割之后的列表. 比如: 把英文句子分割为单词组成的列表
1text = 'Welcome to CodeId'2result = re.split(r'\W+',text)3print(result)4# 结果为:['Welcome', 'to', 'CodeId']
参数 maxsplit 为最大分割次数, 默认是 0 表示无限分割.
1text = 'Welcome to CodeId'2result = re.split(r'\W+',text,maxsplit=1)3print(result)4# 结果为:['Welcome', 'to CodeId']5# 最大分割一次 剩下的部分 作为列表的最后一个元素
注意: 如果在正则表达式中使用组括号, 则正则表达式中所有组的文本也会作为结果列表的一部分返回.
- 1text = 'Welcome to CodeId'2result = re.split(r'(\W+)',text)3print(result)4# 结果为:['Welcome', '','to',' ','CodeId']
- re.findall(pattern,string,flags = 0 )
作用: 从左到右对字符串进行扫描, 以列表的形式返回所有与正则表达式匹配的子串. 比如: 匹配一句话中所有的带小数点的数
1text = '我有 3.5 元钱, 给你 1.5 元, 我还剩 2 元'2result = re.findall(r'-?\d+\.\d+',text)3print(result)4# 结果为 ['3.5', '1.5']
注意: 如果正则表达式中存在一个组, 则返回组列表; 如果正则表达式中有多个组, 这将是一个元组列表.
- 1text = '我有 3.5 元钱, 给你 1.5 元, 我还剩 2 元'2result = re.findall(r'(-?\d+\.\d+)',text) # 一个组 3print(result)4# 结果为 ['3.5', '1.5']5result = re.findall(r'(-?\d)+(\.\d+)',text) # 多个组 6print(result)7# 结果为 [('3', '.5'), ('1', '.5')]
- re.finditer(pattern,string,flags = 0)
作用: 从左到右对字符串进行扫描, 以迭代器的形式返回所有与正则表达式匹配的子串. 比如: 上面的例子 , 换成以迭代器的形式返回
- 1# 匹配一句话中所有的带小数点的数 2text = '我有 3.5 元钱, 给你 1.5 元, 我还剩 2 元' 3result = re.finditer(r'-?\d+\.\d+',text) # 返回一个迭代器 4print(result) 5# 结果为 <callable_iterator object at 0x0000025D2B81B320> 6for s in result: 7 # 每个元素都是 匹配对象 8 print(s.group()) 9# 结果为: 10'''113.5121.513'''
- re.sub(pattern,repl,string,count = 0,flags = 0)
作用: 把字符串中与正则表达式匹配的子串替换为 repl. repl 可以是一个字符串也可以是一个函数.
repl 是一个字符串时, 可以处理任何转义字符比如:
处理普通字符串
1# 把关键信息替换为 ****, 比如手机号 2text = '有事请拨打电话: 15589878888'3result = re.sub(r'(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}','****',text)4print(result)5# 结果为: 有事请拨打电话:****
反向引用
1# 隐藏手机号的中间四位数 2text = '有事请拨打电话: 15589878888'3# 字符串 r'\1****\3' 中的 \1 和 \ 3 就是应用组 1 和组 3 的内容 4result = re.sub(r'(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])(\d{4})(\d{4})',r'\1****\3',text)5print(result)6# 结果为: 有事请拨打电话: 155****8888
注: 除了上述的字符转义和反向引用外, 使用 \ g<name > 还可以引用那些使用 (?P<name>...)语法定义的组. 同时 \ g<number > 等价于 \number,\g<number > 在替代方法中表达的更加清楚. 后面会进行举例. 反向引用 \g<0 > 替换正则表达式中匹配的整个子串.
repl 是一个函数时, 这个函数的参数是一个单匹配对象, 并返回一个替换的字符串. 比如:
1def dashrepl(matchobj): 2 if matchobj.group(0) == '-': 3 return '' 4 else: 5 return'*'6result = re.sub(r'-{1,3}', dashrepl,'pro--a--gram-files') 7print(result) 8# 结果为: pro*a*gram files 910text ="JGood is a handsome boy, he is cool, clever, and so on..."11print(re.sub(r'\S+', lambda m:'['+m.group(0)+']', text,0))12# 结果为:[JGood] [is] [a] [handsome] [boy,] [he] [is] [cool,] [clever,] [and] [so] [on...]
参数 count 用于控制最大替换次数. count 必须是一个非负整数. 如果省略或为零, 则所有匹配的都将被替换. 比如:
- 1result = re.sub(r'-',r'*','------------------',count=4)2print(result)3# 结果为:****--------------4result = re.sub(r'-',r'*','------------------',count=8)5print(result)6# 结果为:********----------
- re.subn(pattern,repl,string,count = 0,flags = 0)
作用: 和 re.sub()一样, 只是 re.subn()返回的是一个元组. 元组里面的内容包括替换后的字符串, 和替换的次数比如:
- 1# 把一些私密信息替换为 ****, 比如手机号 2text = '有事请拨打电话: 15589878888, 以前的手机号: 15888886666 不在使用'3result = re.subn(r'(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}','****',text)4print(result)5# 结果为:('有事请拨打电话:****, 以前的手机号:**** 不在使用', 2)
- re.escape(pattern)
作用: 对字符串中的特殊字符加上转义, 也就是在每个特殊字符前面加上 \
比如:
- 1result = re.escape('CodeId*&@_.\.')2print(result)3# 结果为 CodeId\*\&\@_\.\\\.
- re.purge()
作用: 清除正则表达式缓存.
re.compile(pattern,flags = 0)
作用: 把一个正则表达式编译为正则表达式对象, 它可用于匹配 match(), search()以及其他方法. 比如:
1com = re.compile('CodeId')2result = com.search('Welcome to CodeId.CodeId')3print(result.start())4# 结果是 11
注: 正则表达式对象的匹配方法和上面介绍的模块级匹配方法 在得到效果上是一样的, 但是效率上有所不同, re.compile()是对正则表达式进行一次编译, 然后保存便以后重用, 适合那些单个程序中多次使用的正则表达式. 正则表达式对象的方法在参数上和上面的方法有些不同. 比如:
- Pattern.match(string [,pos [,endpos ] ])
- .
参数 pos 用于设置字符串在什么位置开始匹配.
参数 endpos 用于设置字符串最长的匹配距离. 其他的所有方法和上面差不多 不在细讲, 可以查看
https://docs.python.org/3/library/re.html
了解更多详细的内容.
匹配对象(Match)
匹配对象的布尔值始终返回 True. 由于 match()和 search()在没有匹配时返回 None, 因此我们可以通过 if 语句测试是否是匹配对象. 比如:
- 1result = re.search(r"CodeId", "Welcome to CodeId")2if result :3 print('Yes')4# 结果为 Yes
- Match.expand(template)
作用: 把模板字符串 template 中指定的位置 替换为 指定组的内容. template 中可以使用 \id,\g<id > 或 \g<name > 引用分组, 但不能使用编号 0. \id 与 \ g<id > 是等价的; 如果你想表达 \1 之后是字符'0', 只能使用 \g<1>0, 因为 \ 10 将被认为是第
10
个分组.
比如: 匹配日期
- 1# 匹配日期 2data = '2018-8-9' 3result = re.fullmatch(r'^(\d{4})-(\d{1,2})-(?P<day>\d{1,2})$',data) 4 5expand = result.expand(r'今天是 \1 年 \g<2> 月 \g<day> 号') 6print(expand) 7# 结果为 今天是 2018 年 8 月 9 号 8 9print(result.group())10# 结果为 2018-8-9
- Match.group([ group1,... ] )
作用: 返回匹配的一个或多个子组. 其中如果有一个参数, 结果是返回一个单一的字符串; 如果有多个参数, 则结果是返回每个参数对应的组内容 组成的 元组. 没有参数, group1 默认为 0(整个匹配结果被返回). 如果 groupN 参数为零, 则相应的返回值是整个匹配的字符串比如:
1data = '2018-8-9' 2result = re.fullmatch(r'^(\d{4})-(\d{1,2})-(?P<day>\d{1,2})$',data) 3print(result.group()) # 没有参数时 4# 结果为 2018-8-9 5print(result.group(1)) # 一个参数时 6# 结果为 2018 7print(result.group(1,2)) # 两个参数时 8# 结果为 ('2018', '8') 9print(result.group(1,2,3,0)) # 参数中有为 0 的 10# 结果为 ('2018', '8', '9', '2018-8-9')
如果组编号为负数或大于正则表达式中定义的组数, 则会引发 IndexError 异常.
1print(result.group(4)) # 超过组数 2# 结果为 IndexError: no such group
如果正则表达式使用 (?P<name>...) 语法, 则 groupN 参数也可以是通过其组名称来访问组内容.
1print(result.group('day')) # 通过组名称 2# 结果为 9
如果一个组匹配多次, 只能访问最后一次匹配. 注: 返回结果还可以通过数组的方式来访问, 这得益于
Match.__getitem__(g)
方法, 它是在
3.6
版本中新加的.
- 1data = '2018-8-9'2result = re.fullmatch(r'^(\d{4})-(\d{1,2})-(?P<day>\d{1,2})$',data)3print(result[0])4# 结果为 2018-8-95print(result[1])6# 结果为 20187print(result['day'])8# 结果为 9
- Match.groups(default=None)
作用: 从 1 开始, 返回一个包含匹配所有子组的元组. 参数 default 为那些没有匹配成功的子组设置默认值. 没有参数时默认是 None. 比如: 匹配浮点数
- 1result = re.match(r"(\d+)\.?(\d+)?", "24")2print(result.groups())3# 结果为 ('24', None)4print(result.groups('0')) # 设置默认参数为 05# 结果为 ('24', '0')
- Match.groupdict(default=None)
作用: 对于使用 (?P<name>...) 语法的所有子组, 以字典的形式返回. 默认参数 default 用于那些没有匹配成功的子组; 它默认为 None
1result = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")2print(result.groupdict())3# 结果为 {'first_name': 'Malcolm', 'last_name': 'Reynolds'}
Match.start([group])和 Match.end([group])
作用: 返回按组匹配子串的开始和结束索引; 组默认为零(意味着整个匹配的子字符串). 如果组没有匹配成功则返回 -1. 比如:
- 1result = re.match(r"(\d+)\.?(\d+)?", "24.59")2print(result.start()) # 整个串的开始索引 3# 结果为 04print(result.end()) # 整个串的结束索引 5# 结果为 56print(result.start(2)) # 第二组的开始索引 7# 结果为 38print(result.end(2)) # 第二组的结束索引 9# 结果为 5
- Match.span([group])
作用: 返回一个由匹配子组的开始和结束组成的元组. 如果分组没有成功匹配, 返回(-1,-1). 比如:
1result = re.match(r"(\d+)\.?(\d+)?", "24.59")2print(result.span())3# 结果为 (0, 5)4print(result.span(2))5# 结果为 (3, 5)
来源: https://juejin.im/entry/5b41d0fbf265da0fa6448945