re正则表达式用于判断字符串是否符合某种规则,或者从字符串中替换某种符合规则的子字符串以及提取子字符串。正则表达式本身也是一个字符串,只是字符串里的字符具有特殊含义。
我们做如下规定:
(1)一律使用变量pattern来使用正则表达式;
(2)为了防止字符串本身的转义字符发生作用,在正则表达式前一律加r。
正则表达式的编写规则
1.1、表示类型的字符
元字符 | 意义 |
---|---|
. | 匹配除换行符以外的任意字符 |
\w | 匹配字母、数字、下划线 |
\s | 匹配任何空白字符,包括空格、制表符、换页符 |
\d | 匹配数字字符 |
\W | 匹配非字母、数字、下划线 |
\S | 匹配任何非空白字符 |
\D | 匹配非数字字符 |
[ ] | 字符集合,匹配其中的任意一个字符 |
说明:如果这些元字符后没有表示数量的元字符,那么只会匹配一个。
[ ]字符集合,可以匹配其中任意一个字符,除了^、 -、 ]、 \ 以外,其他字符都表示字符本身。’^’ 放在第一个位置时,表示否定,放在其他位置时表示’^’ 本身;’-’ 放在中间表示‘到’的意思,放在最前或最后都表示’-’ 本身;‘ ] ’放在第一个位置时表示‘ ] ’ 本身,放在其他位置表示与前面的‘ [ ’配对的终止符号;“ \ ”转义字符。
先上代码,后面解释出现的字符。
import re
m=re.findall('\w','123_#-我爱Python')#匹配数字、字母、下划线、汉字
print(m)
m=re.findall('^[a-zA-Z]\d{1,3}OK$','a25OK')#表示以一个字母开头,中间1-3个数字,以OK结尾的字符
print(m)#[]匹配任意一个
['1', '2', '3', '_', '我', '爱', 'P', 'y', 't', 'h', 'o', 'n']
['a25OK']
1.2、表示数量的字符
元字符 | 意义 |
---|---|
* | 匹配任意数量 |
? | 匹配0次或1次 |
+ | 匹配一次或多次 |
{n} | 匹配n次 |
{n:} | 匹配至少n次 |
{n:m} | 匹配最少n次,最多m次 |
1.3、表示位置的字符
元字符 | 意义 |
---|---|
^ | 匹配字符串的起始位置,在[ ]中表否定 |
$ | 匹配字符串的结束位置 |
\b | 匹配单词边界 |
\B | 匹配非单词边界 |
import re
m=re.findall(r'^[-a]\d','a2534_OK')
print(m)
m=re.findall(r'^[-a]\d+','a2534_OK')
print(m)
m=re.findall('^[a-zA-Z]\d{1,3}OK$','a25OK')#表示以一个字母开头,中间1-3个数字,以OK结尾的字符
print(m)#[]匹配任意一个
m=re.findall(r'^[a-zA-Z]\d{1,3}OK$','a25234dsfOK')#匹配失败
print(m)
['a2']
['a2534']
['a25OK']
[]
1.4、分组、小括号()
对单个字符串进行重复,可以再字符串后面跟上表示位置的字符即可,但是如果要对多个字符进行重复怎么办呢?此时就要用到分组,可以使用小括号()来指定要重复的子表达式,然后对这个子表达式进行重复。
例如(abc)?表示0个或1个abc。
再如,要从一个类似于“010-88888888”的固定电话号码字符串中提取区号和电话号码,同样需要用到分组。可以用r‘(\d{3-4}-{8})’得到结果。
下面是几个简单功能。
1.捕获组:(……)
匹配……并捕获匹配结果,并自动设置租号。这里仅提取……部分内容,不提取()外面的内容。
import re
pattern = r'(\d{3,4})-(\d{8})'
dst_str = "010-88888888"
m = re.findall(pattern,dst_str)
print(m)
[('010', '88888888')]
2、无捕获组:( ?: ……)
不单独提取与……相匹配的内容,而是要与()外面的内容一起提取。
import re
pattern = r'(?:\d{3,4})-(?:\d{8})'
dst_str = "010-88888888"
m = re.findall(pattern,dst_str)
print(m)
['010-88888888']
3、前向界定:(?<=……)、前向否定界定:(?<!……)、后向界定:(?>=……)、后向界定:(?!……)
写出“在<h1>之后且在</h1>之前”的表达式。
pattern = r'(?<=<h1>).*(?=</h1>)'
dst_str = r'<html><title><h1>HTML页面</h1></title>'
['HTML页面']
1.5、或规则 ‘ | ’
在正则表达式中使用‘|’时,例如: A|B 表示只要满足A或B就可以匹配。
pattern = r"I am a teacher | student",则A=“I am a teacher”, B=“student”
pattern = r"I am a (?:teacher | student)",则A=“teacher”, B=“student”
1.6、贪婪匹配与非贪婪匹配
贪婪匹配:在满足条件时,匹配尽可能长的字符串。非贪婪匹配:在满足匹配时,匹配尽可能短的字符串,只要能匹配即可。默认采取贪婪匹配模式。
如果需要修改为非贪婪匹配模式,只需要在数量符后面加上"?"即可。 *?、 +?、 ??、 {n,m}?、 {n,}?。使用时要在表达式前面加r。
例如:
①yyyy-yy-yy,其中y为数字。
pattern = r'^(?:\d{4})-(?:\d{2})-(?:\d{2})$'
②由大小写字母、数字组成,且长度在[8,20]
pattern =r'[a-zA-Z0-9]{8,20}$'
③检验手机号:以13,15,18开头的手机号
pattern =r'^(?:13|15|18)\d{9}$'
④从字符串中提取在<ul>XXX</ul>间的字符串XXX
pattern =r'(?<=<ul>).*?(?=</ul>)'