Bootstrap

Python正则表达式学习

基本匹配格式

这是元字符的完整列表

. ^ $ * + ? { } [ ] \ | ( )

这里列举常见匹配组合,并说明举例

格式说明
.任意一个字符
*****前面字符出现0次及以上
+前面字符出现1次及以上
前面字符出现0次或者1次,home-?brew可以匹配 homebrewhome-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;

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;