目录
一、概述
正则表达式是一种强大的字符串匹配工具,通过定义搜索模式,可以在文本中搜索、替换符合条件的字符串。在 Python 中,正则表达式模块由 re
提供支持。本文将详细介绍正则表达式的语法、常用函数和高级用法。
二、基本概念
模式字符串
正则表达式由模式字符串定义,它包含了正则表达式的语法和符号。
原始字符串
建议使用原始字符串(前面带有r
的字符串)来表示模式字符串,这样可以避免转义字符带来的混淆。
python
pattern = r'\bfoo\b'
编译正则表达式
虽然可以直接使用正则表达式,但编译正则表达式可以提高效率,尤其是在多次使用同一表达式时。
python
compiled_pattern = re.compile(r'\bfoo\b')
三、正则表达式的基本模式匹配
字符匹配
.
:匹配除换行符以外的任何单个字符[...]
:匹配字符集合中的一个字符[^...]
:匹配不在字符集合中的一个字符\d
:匹配任何数字,等价于[0-9]
\D
:匹配任何非数字字符,等价于[^0-9]
\s
:匹配任何空白字符,包括空格、制表符、换页符等,等价于[ \t\n\r\f\v]
\S
:匹配任何非空白字符,等价于[^ \t\n\r\f\v]
\w
:匹配任何字母数字字符,等价于[a-zA-Z0-9_]
\W
:匹配任何非字母数字字符,等价于[^a-zA-Z0-9_]
锚点
^
:匹配字符串的开头$
:匹配字符串的结尾\A
:匹配字符串的开始(不受多行模式的影响)\Z
:匹配字符串的结束(不受多行模式的影响)\b
:匹配一个单词边界\B
:匹配非单词边界
量词
*
:匹配前面的子表达式零次或多次+
:匹配前面的子表达式一次或多次?
:匹配前面的子表达式零次或一次{n}
:匹配前面的子表达式恰好n次{n,}
:匹配前面的子表达式至少n次{n,m}
:匹配前面的子表达式至少n次,但不超过m次
四、常用函数
re.match()
re.match()
函数从字符串的开始处匹配正则表达式。如果匹配成功,返回一个匹配对象;否则返回None
。
python
match = re.match(r'\d+', '123abc')
if match:
print('Found:', match.group(0))
re.search()
re.search()
函数在整个字符串中搜索匹配的正则表达式,返回第一个匹配对象。
python
search = re.search(r'\d+', 'abc123def')
if search:
print('Found:', search.group(0))
re.findall()
re.findall()
函数返回字符串中所有匹配正则表达式的部分的列表。
python
findall = re.findall(r'\d+', '123abc456def')
print('All matches:', findall)
re.finditer()
re.finditer()
函数返回一个迭代器,其中包含字符串中所有匹配正则表达式的部分。
python
for match in re.finditer(r'\d+', '123abc456def'):
print('Found:', match.group(0))
re.sub()
re.sub()
函数用于替换字符串中匹配正则表达式的部分。
python
replaced = re.sub(r'\d+', 'number', '123abc456def')
print('Replaced:', replaced)
五、高级主题
分组和捕获
使用圆括号进行分组,可以在后面引用这些分组。
python
grouped = re.search(r'(\d+).+(\d+)', '123abc456def')
if grouped:
print('First group:', grouped.group(1))
print('Second group:', grouped.group(2))
非贪婪匹配
在Python的re模块中,正则表达式默认是贪婪匹配。这意味着在进行匹配时,正则表达式会尽可能地匹配更多的字符。
在量词(*
, +
, ?
, {n,m}
)后面加上?
,可以进行非贪婪匹配,即尽可能少地匹配字符。
python
nongreedy = re.search(r'\d+?', '123abc')
if nongreedy:
print('Non-greedy match:', nongreedy.group(0))
前瞻和后顾(零宽断言)
使用前瞻和后顾可以在不包含在匹配中的情况下,断言此位置前后是否能匹配模式。
- 正前瞻
(?=...)
:匹配...前面的位置。 - 负前瞻
(?!...)
:匹配不在...前面的位置。 - 正后顾
(?<=...)
:匹配...后面的位置。 - 负后顾
(?<!...)
:匹配不在...后面的位置。
python
lookahead = re.search(r'\d(?=\D)', '123abc')
if lookahead:
print('Lookahead match:', lookahead.group(0))
六、编译正则表达式
re.compile()
re.compile()
函数是 re
模块中的一个重要函数,它用于将正则表达式的字符串形式编译成一个 Pattern
对象。预编译可以让你在后续的查找或匹配中重复使用该正则表达式,而无需每次使用时都重新编译,这样可以提高效率。
python
import re
# 将正则表达式编译成Pattern对象
pattern = re.compile(r'\d+') # 匹配一个或多个数字
# 使用Pattern对象进行匹配
match_result = pattern.match('123abc')
if match_result:
print(match_result.group()) # 输出:123
search_result = pattern.search('abc123def')
if search_result:
print(search_result.group()) # 输出:123
# 使用Pattern对象查找所有匹配项
findall_result = pattern.findall('123abc456def')
print(findall_result) # 输出:['123', '456']
# 使用Pattern对象进行迭代查找
for match in pattern.finditer('123abc456def'):
print(match.group()) # 输出:123 然后 456
# 使用Pattern对象替换字符串中的模式
sub_result = pattern.sub("#", '123abc456def')
print(sub_result) # 输出:#abc#def
re.compile()
函数接受一个额外的标志参数 flags
,这些标志可以改变正则表达式的工作方式。例如:
re.IGNORECASE
或re.I
:忽略大小写。re.MULTILINE
或re.M
:多行模式,改变^
和$
的行为。re.DOTALL
或re.S
:使.
匹配任何字符,包括换行符。
例如,如果我们想让正则表达式忽略大小写,可以这样编译它:
python
pattern = re.compile(r'[a-z]+', re.I)
这个编译后的 Pattern
对象可以用来匹配任意字母序列,不论大小写。
七、错误处理
使用re模块时,可能会遇到re.error
异常,通常是因为正则表达式的语法错误。
python
try:
re.search(r'(\d', '123abc') # 缺少闭合的圆括号
except re.error as e:
print('Regex error:', e)
这个简介涵盖了Python中re
模块的基本使用和主要功能。要精通正则表达式,需要大量的练习和对复杂文本模式的理解。正则表达式是一个强大的工具,但也需要谨慎使用,因为复杂的表达式可能难以维护和理解。