正则表达式(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