基本匹配格式
这是元字符的完整列表
. ^ $ * + ? { } [ ] \ | ( )
这里列举常见匹配组合,并说明举例
格式 | 说明 |
---|---|
. | 任意一个字符 |
***** | 前面字符出现0次及以上 |
+ | 前面字符出现1次及以上 |
? | 前面字符出现0次或者1次,home-?brew 可以匹配 homebrew 或 home-brew |
.* | 贪婪 |
.*? | 非贪婪 |
( ) | 仅保留括号里的内容 |
[] | 匹配单个字符的范围 |
{} | 匹配的次数 |
^ | 取反或者匹配字符串的开头 |
\ | 转义特殊字符或匹配字符类 |
| | 表示或,`Crow |
$ | 匹配行的末尾,定义为字符串的结尾,或者后跟换行符的任何位置 |
这里以字符串str为例,参考
https://zhuanlan.zhihu.com/p/139596371
https://docs.python.org/zh-cn/3/howto/regex.html#matching-characters
str = 'aabbabaabbaa'
“ . ” 任意一个字符
一个"."就是匹配除 \n (换行符)以外的任意一个字符
print(re.findall(r'a.b', str)) #['aab', 'aab']
“ * ” 前面字符出现0次及以上
*前面的字符出现0次或以上
print(re.findall(r'a*b', str)) #['aab', 'b', 'ab', 'aab', 'b']
“ .* ” 贪婪
贪婪,匹配从.*前面为开始到后面为结束的所有内容
print(re.findall(r'a.*b', str)) #['aabbabaabb']
“ .*?” 非贪婪
非贪婪,遇到开始和结束就进行截取,因此截取多次符合的结果,中间没有字符也会被截取
print(re.findall(r'a.*?b', str)) #['aab', 'ab', 'aab']
“ ( )” 仅保留括号里的内容
与非贪婪比较
print(re.findall(r'a(.*?)b', str)) #['a', '', 'a']
“ [ ]” 匹配单个字符的范围
str = '''abc1234de12f4567'''
# 匹配0 1 2 b c字符
print(re.findall(r'[0-2b-c]', str)) #['b', 'c', '1', '2', '1', '2']
# *表示前面字符出现0次以上, +表示前面字符出现1次以上
print(re.findall(r'[0-9]*', str)) #['', '', '', '1234', '', '', '12', '', '4567', '']
print(re.findall(r'[0-9]+', str)) #['1234', '12', '4567']
“ { }” 匹配的次数
str = '''abc1234de12f4567'''
#a/{1,3}b 将匹配 'a/b', 'a//b' 和 'a///b'
# 匹配2次
print(re.findall(r'[0-9]{2}', str)) #['12', '34', '12', '45', '67']
# 匹配2次以上,且尽可能的大
print(re.findall(r'[0-9]{2,}', str)) #['1234', '12', '4567']
# 匹配2-3次,且尽可能的大
print(re.findall(r'[0-9]{2,3}', str)) #['123', '12', '456']
“^” 取反或者匹配字符串的开头
str = '''abc1234de12f4567'''
# [^a]表示匹配除了a的任意字符
# [^0-9]表示匹配一个非数字的字符
# [^a-zA-Z0-9]表示匹配一个非字母也非数字的字符
# 在括号外表示匹配字符串的开头位置
print(re.findall(r'^abc', str)) #['abc']
print(re.findall(r'^123', str)) #[]
“\” 转义特殊字符或匹配字符类
str = '''abc1234de12f4567'''
# [\^abc]表示匹配^或a或b或c
# [^\^]表示匹配除了^外的任意字符
#\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]
re下的方法
match
用于在给定的字符串开头进行模式匹配,即可以通过此方法来判断目标的格式是否符合要求
# 正常匹配成功
print(re.match(r'1[3-9]\d{9}', "13312345678"))
# <re.Match object; span=(0, 11), match='13312345678'>
# 尾部加字符匹配成功
print(re.match(r'1[3-9]\d{9}', "133123456789"))
# <re.Match object; span=(0, 11), match='13312345678'>
# 头部加字符匹配失败
print(re.match(r'1[3-9]\d{9}', "8613312345678"))
# None
# 全匹配
print(re.match(r'^1[3-9]\d{9}$', "13312345678"))
# <re.Match object; span=(0, 11), match='13312345678'>
print(re.match(r'^1[3-9]\d{9}$', "133123456789"))
# None
search
与match不同的是search在整个字符串中匹配
# 前后有字符不影响匹配,如果失败和match一样返回None
print(re.search(r'1[3-9]\d{9}', "8613312345678"))
# <re.Match object; span=(2, 13), match='13312345678'>
# 仅会匹配成功第一个符合的对象
print(re.search(r'1[3-9]\d{9}', "8613312345678aaa13312345678"))
# <re.Match object; span=(2, 13), match='13312345678'>
findall
用于在给定的字符串中查找所有匹配的模式,并以列表的形式返回匹配结果
sub
对正则表达式进行替换
split
以匹配成功的正则表达式进行分割字符串,返回字符串列表
escape
转义特殊字符,可以不必使用转义字符
“ re.S” 不对\n中断
str = '''aabbab
aabbaa
bb''' #后面多加了2个b
print(re.findall(r'a.*?b', str)) #['aab', 'ab', 'aab']
print(re.findall(r'a.*?b', str, re.S)) #['aab', 'ab', 'aab', 'aa\n b']
Demo
https://bornforthis.cn/blog/2023/12month/python-regex.html#solution
制作符号表
这里必须使用非贪婪,不然所有返回都是0x0000b30a
str = '''
.text.rtcm3_decode_msm7
0x0000a514 0x442 ./baselib/src/rtcmlib.o
0x0000a514 rtcm3_decode_msm7
.text.rtcm3_decode_1019
0x0000a956 0x34a ./baselib/src/rtcmlib.o
0x0000a956 rtcm3_decode_1019
.text.rtcm3_decode_1044
0x0000aca0 0x33e ./baselib/src/rtcmlib.o
0x0000aca0 rtcm3_decode_1044
.text.rtcm3_decode_1042
0x0000afde 0x32c ./baselib/src/rtcmlib.o
0x0000afde rtcm3_decode_1042
.text.rtcm3_decode_1045
0x0000b30a 0x336 ./baselib/src/rtcmlib.o
0x0000b30a rtcm3_decode_1045
'''
for i in ['rtcm3_decode_msm7', 'rtcm3_decode_1019', 'rtcm3_decode_1044']:
ret = re.findall(i + r".*?0x(\w{8}).*0x", str, re.S)
print(i + " = " + ret[0] + ";")
#rtcm3_decode_msm7 = 0000a514;
#rtcm3_decode_1019 = 0000a956;
#rtcm3_decode_1044 = 0000aca0;