正则表达式(Regular Expression, 简称 Regex)是一种用于匹配字符串中字符模式的强大工具。在Python中,正则表达式由
re模块支持。正则表达式可以用于搜索、编辑和处理文本。
正则表达式语法
正则表达式由普通字符和特殊字符(元字符)组成。普通字符包括字母、数字和标点符号,匹配其自身。特殊字符用于匹配特定的字符集、位置或重复。
| 类型 | 模式 | 描述 | 示例 | 
|---|---|---|---|
| 元字符 | . | 匹配任意单个字符,除换行符 | a.b匹配aab,a9b | 
| 元字符 | ^ | 匹配字符串的开头 | ^abc匹配abc | 
| 元字符 | $ | 匹配字符串的结尾 | abc$匹配abc | 
| 元字符 | * | 匹配前一个字符零次或多次 | a*匹配a,aaa | 
| 元字符 | + | 匹配前一个字符一次或多次 | a+匹配a,aaa | 
| 元字符 | ? | 匹配前一个字符零次或一次 | a?匹配a, 或空 | 
| 元字符 | {n} | 匹配前一个字符恰好 n 次 | a{3}匹配aaa | 
| 元字符 | {n,} | 匹配前一个字符至少 n 次 | a{2,}匹配aa,aaa | 
| 元字符 | {n,m} | 匹配前一个字符至少 n 次,至多 m 次 | a{2,3}匹配aa,aaa | 
| 元字符 | [] | 匹配括号内的任意一个字符 | [abc]匹配a,b,c | 
| 元字符 | | | 当匹配字符串时,如果左边的模式不匹配,会尝试右边的模式 | 表示“或”操作 | 
| 元字符 | \ | 转义字符,用于匹配特殊字符或表示特殊序列 | \.匹配. | 
| 特殊序列 | \d | 匹配任何数字,相当于 [0-9] | \d匹配7,4 | 
| 特殊序列 | \D | 匹配任何非数字字符,相当于 [^0-9] | \D匹配a,! | 
| 特殊序列 | \w | 匹配任何字母数字字符和下划线,相当于 [a-zA-Z0-9_] | \w匹配a,1,_ | 
| 特殊序列 | \W | 匹配任何非字母数字字符和下划线,相当于 [^a-zA-Z0-9_] | \W匹配!,@,`` | 
| 特殊序列 | \s | 匹配任何空白字符,相当于 [ \t\n\r\f\v] | \s匹配 ``,\t | 
| 特殊序列 | \S | 匹配任何非空白字符,相当于 [^ \t\n\r\f\v] | \S匹配a,1 | 
| 特殊序列 | \b | 匹配单词边界 | \bword\b匹配word | 
| 特殊序列 | \B | 匹配非单词边界 | \Bword\B | 
| 分组 | () | 用括号将表达式括起来作为一个分组 | (abc)+匹配abcabc | 
| 非捕获分组 | (?:…) | 用括号将表达式括起来作为一个非捕获分组 | (?:abc)+ | 
| 前向查找 | (?=…) | 匹配前面是某个模式的文本(不包含该模式) | \d+(?= apples) | 
| 后向查找 | (?<=…) | 匹配后面是某个模式的文本(不包含该模式) | (?<=123 )\w+ | 
| 非前向查找 | (?!..) | 匹配前面不是某个模式的文本 | \d+(?! apples) | 
| 非后向查找 | (?<!..) | 匹配后面不是某个模式的文本 | (?<!123 )\w+ | 
re模块基础
 
导入 re 模块
import re
基本匹配函数
- re.match(): 从字符串的开头匹配正则表达式模式。
pattern = r'\d+'
string = '123abc456'
match = re.match(pattern, string)
if match:print('Match:', match.group())  # 输出: '123'
- re.search(): 搜索字符串,返回第一个匹配的正则表达式模式。
search = re.search(pattern, string)
if search:print('Search:', search.group())  # 输出: '123'
- re.findall(): 返回字符串中所有匹配正则表达式模式的列表。
findall = re.findall(pattern, string)
print('Findall:', findall)  # 输出: ['123', '456']
- re.finditer(): 返回一个迭代器,包含字符串中所有匹配正则表达式模式的Match对象。
for match in re.finditer(pattern, string):print('Finditer:', match.group())  # 输出: '123' 和 '456'
- re.sub(): 替换字符串中所有匹配正则表达式模式的子串。
sub = re.sub(pattern, '#', string)
print('Sub:', sub)  # 输出: '#abc#'
re模块进阶
 
分组用括号 () 将表达式的一部分括起来。可以用 group(n) 获取匹配的子串。
pattern = r'(\d+)\s+(\w+)'
string = '123 apples'
match = re.search(pattern, string)
if match:print('Group 1:', match.group(1))  # 输出: '123'print('Group 2:', match.group(2))  # 输出: 'apples'
用 (?:...) 进行非捕获分组,不保存匹配的子串。
pattern = r'(?:\d+)\s+(\w+)'
match = re.search(pattern, string)
if match:print('Group 1:', match.group(1))  # 输出: 'apples'
前后查找
- 前向查找(Lookahead): 匹配前面是某个模式的文本(不包含该模式)。
pattern = r'\d+(?=\s+apples)'
match = re.search(pattern, string)
if match:print('Lookahead:', match.group())  # 输出: '123'
- 后向查找(Lookbehind): 匹配后面是某个模式的文本(不包含该模式)。
pattern = r'(?<=123\s)\w+'
match = re.search(pattern, string)
if match:print('Lookbehind:', match.group())  # 输出: 'apples'
re模块高级
 
使用 re.sub() 函数可以进行更复杂的替换操作,替换字符串可以使用函数。
def replace_func(match):return match.group(1).upper()
pattern = r'(\w+)\s+(\d+)'
string = 'apple 123'
sub = re.sub(pattern, replace_func, string)
print('Sub:', sub)  # 输出: 'APPLE 123'
re.IGNORECASE 或 re.I: 忽略大小写匹配。
re.MULTILINE 或 re.M: 多行模式,^ 和 $ 匹配每一行的开头和结尾。
re.DOTALL 或 re.S: 使 . 匹配包括换行在内的所有字符。
re.VERBOSE 或 re.X: 忽略模式中的空白字符和注释,方便书写复杂正则表达式。
pattern = r'(?i)apple'  # 使用 IGNORECASE
string = 'Apple 123'
match = re.search(pattern, string)
if match:print('Ignorecase:', match.group())  # 输出: 'Apple'
pattern = r'(?m)^apple'  # 使用 MULTILINE
string = 'apple\n123\napple'
matches = re.findall(pattern, string)
print('Multiline:', matches)  # 输出: ['apple', 'apple']
使用 re.compile() 将正则表达式编译成模式对象,以便多次重用,提高效率。
pattern = re.compile(r'\d+')
string = '123 abc 456'
matches = pattern.findall(string)
print('Compiled Findall:', matches)  # 输出: ['123', '456']
示例
使用正则表达式匹配字符串中的时间:
def getTime(text):pattern = re.compile(r'''(\d{4})[.-/年](\d{1,2})[.-/月](\d{1,2})[日]?''', re.VERBOSE)  # YYYY.MM.DD YYYY-MM-DD YYYY/MM/DD YYYY年MM月DD日match = pattern.search(text)  # 查找第一个匹配的日期if match:year, month, day = map(int, match.groups())date = datetime(year, month, day)  # 创建 datetime 对象return dateelse:return None
使用正则表达式匹配字符串中的功率:
def getPower(text):pattern = re.compile(r'(\d+)\s*(千伏|kv|KV|kV)')power = pattern.search(text)if power:return power.groups()[0]else:return None