Python - re 模块 - 函数和匹配对象

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第14天,点击查看活动详情

re.compile(pattern, flags=0)

返回一个正则对象再去调用对象的方法

import re

p = "^1234"
string = "1234"

pattern = re.compile(p)
result = pattern.match(string)
# 等价写法
result = re.match(p, string)
复制代码

建议

  • 如果需要多次使用某个正则表达式,才需要使用re.compile来保存成正则对象以复用
  • re.compile()编译后会被缓存,反复使用的话效率会更高

re.search(pattern, string, flags=0)

  • 找到匹配的第一个位置,并返回一个相应的匹配对象
  • 如果没有匹配,就返回一个 None
  • 匹配对象:<re.Match object; span=(0, 3), match='123'>
import re

string = "1234123"
result = re.search(r"123", string)
print(result.group())

# 打印
123
复制代码

re.match(pattern, string, flags=0)

和 search 类型,但这个函数是检查字符串开头是否匹配,相当于在 pattern 最前面自动加了 ^

import re

string = "4123"
result = re.match(r"123", string)
print(result)

# 打印,因为123不是开头,所以匹配失败
None
复制代码

search() 和 match() 的区别

  • re.match() 检查字符串开头
  • re.search() 检查字符串的任意位置
>>> re.match("c", "abcdef")    # No match
>>> re.search("c", "abcdef")   # Match
<re.Match object; span=(2, 3), match='c'>

>>> re.match("c", "abcdef")    # No match
>>> re.search("^c", "abcdef")  # No match
>>> re.search("^a", "abcdef")  # Match
<re.Match object; span=(0, 1), match='a'>

>>> re.match('X', 'A\nB\nX', re.MULTILINE)  # No match
>>> re.search('^X', 'A\nB\nX', re.MULTILINE)  # Match
<re.Match object; span=(4, 5), match='X'>
复制代码

re.fullmatch(pattern, string, flags=0)

和 match() 一样,检查字符串开头是否匹配

但 fullmatch() 需要将整个字符串和正则表达式进行匹配,只有整个字符串都匹配成功才会返回匹配对象,否则返回 None

import re

string = "4123"
result = re.fullmatch(r"4123", string)
print(result) # 匹配成功,<re.Match object; span=(0, 4), match='4123'>

result = re.fullmatch(r"412", string)
print(result) # 匹配失败
复制代码

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

  • 作用: 用正则表达式来对字符串进行 split
  • maxsplit: split 的次数,超过它,将剩余字符都返回到列表的最后一个元素
import re

string = "23123123123"
result = re.split(r"1", string)
print(result) # ['23', '23', '23','23']

result = re.split(r"1", string, maxsplit=2)
print(result) # ['23', '23', '23123']
复制代码

re.findall(pattern, string, flags=0)

返回所有匹配成功的结果,以字符串列表/元组的形式,从左往右,匹配结果按照找到的顺序返回

import re

string = "23123123123"
result = re.findall(r"23", string)
print(result) # ['23', '23', '23', '23']
复制代码

如果有多个组

>>> re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest')
['foot', 'fell', 'fastest']
>>> re.findall(r'(\w+)=(\d+)', 'set width=20 and height=10')
[('width', '20'), ('height', '10')]
复制代码

re.finditer(pattern, string, flags=0)

和 findall() 一样效果,只不过返回一个迭代器并且保存的是匹配对象

import re

string = "23123123123"
result = re.finditer(r"23", string)
for res in result:
    print(res)

# 打印
<re.Match object; span=(0, 2), match='23'>
<re.Match object; span=(3, 5), match='23'>
<re.Match object; span=(6, 8), match='23'>
<re.Match object; span=(9, 11), match='23'>
复制代码

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

作用:通过正则替换字符串的子串

  • pattern : 正则中的模式字符串
  • repl : 替换的字符串,也可为一个函数
  • string : 要被查找替换的原始字符串
  • count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配
import re

phone = "2004-959-559 # 这是一个国外电话号码"

# 删除注释
phone = re.sub(r'#(.*)', '', phone)

# 删除 -
phone = re.sub(r'-', '', phone)

print(phone) # 2004959559
复制代码

假设 repl 是一个函数

def dashrepl(matchobj):
    if matchobj.group(0) == '-': 
        return ' '
    else: 
        return '-'

res = re.sub('-{1,2}', dashrepl, 'pro----gram-files')

print(res) # pro--gram files
复制代码

什么是匹配对象

像 match(),search() 函数匹配成功会返回一个匹配对象

match = re.search(pattern, string)
if match:
    process(match)
复制代码

Match.group([group1, ...])

  • 返回一个或者多个匹配的子组
  • 如果没有参数,则返回所有匹配结果,结果也是一个字符串
  • 如果只有一个参数,结果就是一个字符串
  • 如果有多个参数,结果就是一个元组(每个参数对应一个项)
m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
print(m.group())
print(m.group(1))
print(m.group(0)) # 
print(m.group(1, 2))

# 打印
Isaac Newton
Isaac
Isaac Newton
('Isaac', 'Newton')
复制代码

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

>>> m = re.match(r"(..)+", "a1b2c3")  # Matches 3 times.
>>> m.group(1)                        # Returns only the last match.
'c3'
复制代码

重点

只有正则表达式里面包含多个 ()才是有多个组

Match.getitem(g)

这个等价于 m.group(g),不过可以通过下标来访问结果

import re

m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
print(m[0])
print(m[1])
print(m[1], m[2])

# 打印
Isaac Newton
Isaac
Isaac Newton
复制代码

Match.groups(default=None)

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

>>> m = re.match(r"(\d+).(\d+)", "24.1632")
>>> m.groups()
('24', '1632')

>>> m = re.match(r"(\d+).?(\d+)?", "24")
>>> m.groups()      # Second group defaults to None.
('24', None)
>>> m.groups('0')   # Now, the second group defaults to '0'.
('24', '0')
复制代码

Match.start([group])、Match.end([group])

  • 返回 group 匹配到的字串的开始和结束标号
  • group 默认为 0,整个匹配的子串
  • 如果 group 匹配失败就返回 -1
import re

m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
print(m.group(), m.start(), m.end())
print(m.group(1), m.start(1), m.end(1))
print(m.group(2), m.start(2), m.end(2))

# 打印
Isaac Newton 0 12
Isaac 0 5
Newton 6 12
复制代码

Match.span([group])

返回一个二元组(m.start(group), m.end(group))

import re

m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
print(m.group(), m.span())
print(m.group(1), m.span(1))
print(m.group(2), m.span(2))

# 打印
Isaac Newton (0, 12)
Isaac (0, 5)
Newton (6, 12)
复制代码

如何使用标志

re.compile(r"123123", re.X)
re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE)
re.match('[a-f]+', '0a3B9', flags=re.IGNORECASE)
复制代码

有哪些常用标志

flagdescription
re.Ire.IGNORECASE忽略大小写
re.Sre.DOTALL.匹配任何字符包括换行符\n,没有这个标志不会匹配换行符

忽略大小写的🌰

import re

s = "AbadC"

r = re.search('[a-z]*', s, flags=re.I)
print(r.group()) # 打印 AbadC
复制代码

re.S 的🌰

import re

s = """Aba\ndC"""

r = re.search('.*', s, flags=re.S)
print(r.group())

# 打印
Aba
dC
复制代码

如果不加 re.S,只会打印 Aba

分类:
后端