1 正则符号初阶
正则表达式需要与相关函数共同使用,对函数的学习可以参考:
Python正则表达式所有函数详解
首先看一下正则表达式中的常用符号
代码举例1:不同符号的组合
rs = r'\D\d' s ='123dws8f833vbalc8d77' res = re.findall(rs,s) print(res)
以上代码寻找的是一个非数字搭配一个数字的字符串,输出结果为:
代码举例2:符号加+,代表连续的一个或多个
rs = r'\w+' s ='12 3dws8#f833vb(alc8)d77' res = re.findall(rs,s) print(res)
以上代码寻找的是一个或多个字母数字下划线的字符串,输出结果为:
代码举例3:匹配字符串开始
使用\A可以只从开始进行字符串的匹配,注意只能放在最左边,如果字符串开头无法匹配上,则直接返回空值:
rs1 = r'\A\d' rs2 = r'\A\d+' rs3 = r'\A\D+' s ='12 3dws8#f833vb(alc8)d77' res1 = re.findall(rs1,s) res2 = re.findall(rs2,s) res3 = re.findall(rs3,s) print(res1, res2, res3)
以上代码的输出结果为:
代码举例4:匹配字符串结束
与\A同理,\Z可以匹配字符串结束,必须放在正则表达式的最右侧,即便是换行符等转义字符,也不能放在\Z的右侧。
rs1 = r'\d\Z' rs2 = r'\d+\Z' rs3 = r'\D+\Z' s ='12 3dws8#f833vb(alc8)d77' res1 = re.findall(rs1,s) res2 = re.findall(rs2,s) res3 = re.findall(rs3,s) print(res1, res2, res3)
代码举例5:匹配单词边界
使用\b匹配单词边界,字母数字下划线以外的字符或转义符,可以被认为是单词边界
rs1 = r'\d+\b' s ='12 3dws8#f833vb(alc8)d77' res1 = re.findall(rs1,s) print(res1)
2 正则符号进阶
前两项的匹配开头与末尾,和\A\Z作用相同,不再重复提供示例代码
代码举例1:匹配a或b
rs = 'a|b' s = 'ac123bc456' print(re.findall(rs,s))
运行结果:[‘a’, ‘b’]
代码举例2:中括号的使用
中括号中任意一个字符匹配即可,需要注意的是,中括号中允许使用\d这类表达,但是不能使用\d+这类表达,因为会被看作\d和+。
rs = '[ab]c' s = 'ac123bc456' print(re.findall(rs,s))
输出是:[‘ac’, ‘bc’]
rs = '[3-9]' #表示3-9的任意字符 s = 'ac123bc456' print(re.findall(rs,s)) 1
输出是:[‘3’, ‘4’, ‘5’, ‘6’]
中括号中数字和字母可以同时使用,如[0-9A-Z],中间不含逗号;[\u4E00-\u9fa5]可以匹配所有汉字;
代码举例3:大括号
通常与其他语法联用,表示前面的字符重复出现几次。{3}表示重复出现3次,{3,7}表示重复出现3至7次,{3,}表示重复出现三次以上。
rs1 = r'[a-z]{2}' s ='12 3dws8#f833vb(alc8)d77' res1 = re.findall(rs1,s) print(res1)
这将输出连续的连个小写字母类型的字符串,输出结果为:[‘dw’, ‘vb’, ‘al’]
如果使用{3,}这类语法,还可考虑和?联用。当?不存在时,为贪婪模式,匹配出的单个字符串将尽可能地长,具体差别通过代码会更加清晰:
rs1 = r'[a-z]{2,}' rs2 = r'[a-z]{2,}?' s ='12 3dws8#f833vbvd(alc8)d77' res1 = re.findall(rs1,s) res2 = re.findall(rs2,s) print(res1,res2) 1
代码举例4:小括号
小括号的主要功能包括组合、捕获和分组。
1.组合功能
rs = r'(\d[a-z]){3}' #组合 s = '1a2b3c44' print(re.fullmatch(rs,s))
上面的代码使用了小括号的组合功能,通过与大括号的结合,将小括号中的内容重复了3次,将会输出1a2b3c
2.捕获功能
url = 'http://www.baidu.com/abcdefg' # 捕获 rs = r'http://(.*?)/' # .代表任意字符,*代表出现任意次(包括0次),?代表非贪婪模式 print(re.findall(rs,url))
上面的代码使用了小括号的捕获功能,捕获的是介于http://和/之间的字符。这段代码的输出是:www.baidu.com 该功能通常与findall函数联用,与其他函数联用时,其可能不再具有捕获的含义
3.分组功能
在Python正则表达式中,小括号与反斜杠的组合可以用于创建分组,以实现对子表达式的分组匹配或分组替换。具体来说,小括号用于指定一个子表达式,而反斜杠后面跟着小括号的数字可以用于引用已定义的子表达式。
(\d{3})-(\d{3}-\d{4})
这个正则表达式将匹配格式为“xxx-xxx-xxxx”的电话号码。其中,小括号将整个正则表达式分成两个子表达式,分别匹配三个数字和“-”符号以及七个数字。你可以在正则表达式中使用\1和\2引用这两个子表达式,以便在后续的匹配或替换中使用它们。
例如,以下代码将使用re.sub函数将匹配的电话号码格式更改为“xxx.xxx-xxxx”:
import re phone_num = "555-555-1234" new_phone_num = re.sub(r"(\d{3})-(\d{3}-\d{4})", r"\1.\2", phone_num) print(new_phone_num)
输出为:555.555-1234
代码举例5:问号
在Python正则表达式中,问号(?)的含义有两种:
表示非贪婪模式:在量词(例如 ,+ 等)后面加上问号表示量词的非贪婪模式,它匹配的内容尽可能少。例如:a.?b 匹配的是最短的 a 和 b 中间的内容,而不是最长的。
表示 0 个或 1 个:单独使用问号表示该字符出现 0 次或 1 次。例如:a?b 可以匹配 ab 和 b,但不能匹配 aab。
import re text = 'aabbcc' # 非贪婪模式 print(re.findall('a.*?b', text)) # 输出 ['ab', 'ab'] # 0 个或 1 个 print(re.findall('a?b', text)) # 输出 ['b', 'ab', 'b', 'ab']
这里有一种有意思的代码就是连续出现了两次问好,比如:
import re text = 'aabbcc' print(re.findall('a??b', text)) # 输出 ['b', 'b']
在这个例子中,两个问号连续匹配的是 a 出现 0 次或 1 次,因此只有 b 被匹配了。