Python re模块 -- 正则表达式


本文只介绍Python中re模块于正则表达式中的应用。正则表达式的相关知识,请参考其它文章。

re模块使用

1. 编译正则表达式对象

# -*- coding: utf-8 -*-

import re
reObj = re.compile(r'\d+', flags=0)
# reObj是正则表达式对象,通过该对象可以进行正则表达式的各种操作(这一节只讲re模块的操作)
# 第一个参数:指定要匹配的正则表达式
# 第二个参数:指定匹配时的规则。(re模块的其它函数也会用到该参数)如下:
# re.A:只匹配ASCII,而不是Unicode。这只对Unicode样式有效,会被byte样式忽略。
# re.DEBUG:显示编译时的debug信息,没有内联标记。
# re.I:进行忽略大小写匹配;表达式如 [A-Z] 也会匹配小写字符。
# re.L:由当前语言区域决定 \w, \W, \b, \B 和大小写敏感匹配。这个标记只能对byte样式有效。这个标记不推荐使用,因为语言区域机制很不可靠。
# re.M:设置以后,样式字符 '^' 匹配字符串的开始,和每一行的开始(换行符后面紧跟的符号);样式字符 '$' 匹配字符串尾,和每一行的结尾(换行符前面那个符号)。
# re.S:让 '.' 特殊字符匹配任何字符,包括换行符;如果没有这个标记,'.' 就匹配 除了 换行符的其他任意字符。
# re.X:这个标记允许你编写更具可读性更友好的正则表达式。例:
a = re.compile(r"""\d +  # the integral part
                   \.    # the decimal point
                   \d *  # some fractional digits""", re.X)

2. 搜索 re.search(pattern, string, flags=0)

扫描整个字符串找到匹配样式的第一个位置,并返回一个相应的匹配对象。如果没有匹配,就返回一个 None 。

# -*- coding: utf-8 -*-

import re
matchObj = re.search(r'\d+', 'ab123c456')
print(matchObj)
# 输出:<re.Match object; span=(2, 5), match='123'>

3. 匹配 re.match(pattern, string, flags=0)

如果 string 开始的0或者多个字符匹配到了正则表达式样式,就返回一个相应的匹配对象 。 如果没有匹配,就返回 None。

# -*- coding: utf-8 -*-

import re
matchObj = re.match(r'\d+', 'ab123c456')
print(matchObj)
# 输出:None

matchObj = re.match(r'\d+', '0ab123c456')
print(matchObj)
# 输出:<re.Match object; span=(0, 1), match='0'>

4. 全匹配 re.fullmatch(pattern, string, flags=0)

如果整个 string 匹配到正则表达式样式,就返回一个相应的匹配对象 。 否则就返回一个 None。

# -*- coding: utf-8 -*-

import re
matchObj = re.fullmatch(r'\d+', 'ab123c456')
print(matchObj)
# 输出:None

matchObj = re.fullmatch(r'\d+', '0123456')
print(matchObj)
# 输出:<re.Match object; span=(0, 7), match='0123456'>

5. 分割 re.split(pattern, string, maxsplit=0, flags=0)

用 pattern 分开 string 。 如果在 pattern 中捕获到括号,那么所有的组里的文字也会包含在列表里。如果 maxsplit 非零, 最多进行 maxsplit 次分隔, 剩下的字符全部返回到列表的最后一个元素。

# -*- coding: utf-8 -*-

import re
result = re.split(r'\d+', 'a123c456d')
print(result)
# 输出:['a', 'c', 'd']

result = re.split(r'(\d+)', 'a123c456d')
print(result)
# 输出:['a', '123', 'c', '456', 'd']

result = re.split(r'\d+', 'a123c456d', 1)
print(result)
# 输出:['a', 'c456d']

# 如果分隔符里有捕获组合,并且匹配到字符串的开始,那么结果将会以一个空字符串开始。结尾也一样。
result = re.split(r'\d+', '0a123c456d7')
print(result)
# 输出:['', 'a', 'c', 'd', '']

6. 全找 re.findall(pattern, string, flags=0)

对 string 返回一个不重复的 pattern 的匹配列表, string 从左到右进行扫描,匹配按找到的顺序返回。

# -*- coding: utf-8 -*-

import re
result = re.findall(r'\d+', 'a123c456d')
print(result)
# 输出:['123', '456']

result = re.findall(r'\d+', 'abcdefghi')
print(result)
# 输出:[]

7. 全找 re.finditer(pattern, string, flags=0)

pattern 在 string 里所有的非重复匹配,返回为一个迭代器 iterator 保存了 匹配对象 。 string 从左到右扫描,匹配按顺序排列。空匹配也包含在结果里。

# -*- coding: utf-8 -*-

import re
result = re.finditer(r'\d+', 'a123c456d')
print(result)
# 输出:<callable_iterator object at 0x00000000022003C8>
for itm in result:
    print(itm)
    # 输出1:<re.Match object; span=(1, 4), match='123'>
    # 输出2:<re.Match object; span=(5, 8), match='456'>


result = re.finditer(r'\d+', 'abcdefghi')
print(result)
# 输出:<callable_iterator object at 0x00000000028FFCC0>
for itm in result:
    print(itm)
    # 输出:因为result没有匹配到任何内容,所以无输出

8. 替换 re.sub(pattern, repl, string, count=0, flags=0)

返回通过使用 repl 替换在 string 最左边非重叠出现的 pattern 而获得的字符串。 如果样式没有找到,则不加改变地返回 string。

# -*- coding: utf-8 -*-

import re
result = re.sub(r'a(\d+)', r'digital\1', 'a1 a2')
print(result)
# 输出:digital1 digital2

如果 repl 是一个函数,那它会对每个非重复的 pattern 的情况调用。这个函数只能有一个 匹配对象 参数,并返回一个替换后的字符串。

# -*- coding: utf-8 -*-

import re

def dash_repl(matchObj):
    return '-'
        
result = re.sub(r'-{2}', dash_repl, 'a--b--c')
print(result)
# 输出:a-b-c

9. 替换 re.subn(pattern, repl, string, count=0, flags=0)

行为与 sub() 相同,但是返回一个元组 (字符串, 替换次数).

# -*- coding: utf-8 -*-

import re

result = re.subn(r'-{2}', r'-', 'a--b--c')
print(result)
# 输出:('a-b-c', 2)

result = re.subn(r'-{2}', r'-', 'a--b--c', 1)
print(result)
# 输出:('a-b--c', 1)

result = re.subn(r'-{3}', r'-', 'a--b--c')
print(result)
# 输出:('a--b--c', 0)

10. 转义 re.escape(pattern)

转义 pattern 中的特殊字符。如果你想对任意可能包含正则表达式元字符的文本字符串进行匹配,它就是有用的。

# -*- coding: utf-8 -*-

import re

print(re.escape('python.exe'))
# 输出:python\.exe

operators = ['+', '-', '*', '/', '**']
print('|'.join(map(re.escape, operators)))
# 输出:\+|\-|\*|/|\*\*

11. 清除 re.purge()

清除正则表达式缓存。

匹配对象

上面部分方法的返回值为匹配对象(形如:<re.Match object; span=(2, 5), match=‘123’>),现在来具体介绍下:

1. 子组 Match.group([group1, …])

返回一个或者多个匹配的子组。

# -*- coding: utf-8 -*-

import re
matchObj = re.search(r'(\d+)c(\d+)', 'ab123c456')
print(matchObj)
# 输出:<re.Match object; span=(2, 5), match='123'>
print(matchObj.group(0))
# 输出:123c456
print(matchObj.group(1))
# 输出:123
print(matchObj.group(2))
# 输出:456
print(matchObj.group(1, 2))
# 输出:('123', '456')

如果正则表达式使用了 (?P<name>…) 语法, groupN 参数就也可能是命名组合的名字:

# -*- coding: utf-8 -*-

import re
matchObj = re.search(r'(?P<first_name>\w+)\s+(?P<last_name>\w+)', 'Coder X')
print(matchObj.group(0))
# 输出:Coder X
print(matchObj.group('first_name'))
# 输出:Coder
print(matchObj.group('last_name'))
# 输出:X

如果一个组匹配成功多次,就只返回最后一个匹配:

# -*- coding: utf-8 -*-

import re
matchObj = re.search(r'(..)+', 'CoderXx')
print(matchObj.group(0))
# 输出:CoderX
print(matchObj.group(1))
# 输出:rX

2. 所有子组 Match.groups(default=None)

返回一个元组,包含所有匹配的子组:

# -*- coding: utf-8 -*-

import re
matchObj = re.search(r'(..)(..)(..)', 'CoderXx')
print(matchObj.groups())
# 输出:('Co', 'de', 'rX')

3. 所有子组 Match.groupdict(default=None)

返回一个字典,包含了所有的 命名子组:

# -*- coding: utf-8 -*-

import re
matchObj = re.search(r'(?P<first_name>\w+)\s+(?P<last_name>\w+)\s+(\w+)', 'Coder X other')
print(matchObj.groupdict())
# 输出:{'first_name': 'Coder', 'last_name': 'X'}

print(matchObj.groups())
# 输出:('Coder', 'X', 'other')

4. 匹配到的位置 Match.start([group]) Match.end([group])

返回 group 匹配到的字串的开始和结束标号:

# -*- coding: utf-8 -*-

import re
matchObj = re.search(r'(\d+)', 'a123b')
print(matchObj.start(), matchObj.end())
# 输出:1 4

5. 匹配到的位置 Match.span([group])

对于一个匹配 m , 返回一个二元组 (m.start(group), m.end(group)) :

# -*- coding: utf-8 -*-

import re
matchObj = re.search(r'(\d+)', 'a123b')
print(matchObj.span())
# 输出:(1, 4)

正则表达式对象

之前提到正则表达式对象就是re.compile(pattern, flags=0)方法的返回值。该对象支持的方法与re模块基本相同,差异如下:

  1. 方法由正则表达式对象直接调用;
  2. 方法里不用指定正则表达式,因为在编译时已经指定了;
  3. 部分方法可为匹配指定开始位置结束位置

一个简单的例子如下:

# -*- coding: utf-8 -*-

import re
reObj = re.compile(r'\d+')
matchObj = reObj.search('a123b')
print(matchObj.group())
# 输出:123

matchObj = reObj.search('a123b', 1, 2)
print(matchObj.group())
# 输出:1

第三方模块

第三方模块regex , 提供了与标准库 re 模块兼容的API接口, 同时还提供了额外的功能和更全面的Unicode支持。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值