筛选符合定义的东西,正则寻找的永远是字符串。
在Python中需要通过正则表达式对字符串进⾏匹配的时候,可以使⽤⼀个Python自带的模块,名字为re。
正则表达式的大致匹配过程是:
1.依次拿出表达式和文本中的字符比较,
2.如果每一个字符都能匹配,则匹配成功;一旦有匹配不成功的字符则匹配失败。
表2 常用函数
函数 |
定义 |
使用方法 |
re.match |
从头开始匹配需要查找的字符,如果不成功会返回空值 |
result = re.match(“正则表达式”, 字符串) |
re.search |
可以查找字符串的任意位置,匹配整个字符串,会返回匹配的内容和匹配的位置,查找到一个匹配后不再向下查找 |
result = re.search(“正则表达式”, 字符串) |
re.findall |
同search函数一样可以匹配整个字符串,查到一个后会继续向下查找,直到字符串末尾,并返回全部符合条件的字符串 |
result = re.findall(“正则表达式”, 字符串) |
re.sub |
用于替换字符串中的值 |
result = re.sub(“正则表达式”, “新内容”,字符串) |
re.spilt |
用于按照给定的字符去切割字符串 |
result = re.spilt(“正则表达式”, 字符串) |
表1 正则表达式预定义
字符 |
功能 |
. |
寻找任意字符(除了\n) |
[ ] |
寻找[ ]中列举的字符 |
\d |
寻找数字,即0-9 |
\D |
寻找⾮数字,即不是数字 |
\s |
寻找空⽩,即空格,tab键 |
\S |
寻找⾮空⽩字符 |
\w |
寻找单词字符,即a-z、A-Z、0-9、_ |
\W |
寻找⾮单词字符 |
* |
寻找前一个字符出现>=0次 |
+ |
寻找前一个字符>=1次 |
? |
寻找前一个字符出现0或1次 |
{m} |
用于验证将前面的模式匹配m次,即限制m位 |
{m,} |
用于验证将前面的模式匹配m次或者多次 |
{m,n} |
用于验证将前面的模式匹配大于等于m次且小于等于n次 |
^ |
匹配字符串开头 |
$ |
匹配字符串结尾 |
目标:5-11位,开头不能是零,以qq = "10471204"为例。
表达式:
result = re.match("^[1-9][0-9]{4,10}$", qq)
print(result)
对应说明:
“^”: 此时表达式中的"^"可有可无,因为使用的是match函数,即从头开始匹配。
“[1,9]”: 首先验证开头不能是0,所以匹配开头一个字符为[1-9]
“[0,9]”: 表示后面的数字可以是从0-9,没有限制。
“{4,10}”: {4,10}表示将前一个匹配模式匹配大于等于4次且小于等于10次。前一个匹配模式即为[0-9],即qq号的第2位到第11位可以是从0到9的任意数字。因为第一位不能为0的限制已经占去一个字符,所以从第2位开始匹配“0到9的任意数字”这个条件。且题中限制最短5位,所以至少需要匹配4次。即{4,10}中的4表达的意思,若给出的字符串小于5位则匹配不成功。题中限制最长11位,所以至多只能匹配10次。即{4,10}中的10表达的意思,若给出的字符串大于11位则匹配不成功。
“$”: 表示要一直匹配到结尾。
输出结果:
其中span表示匹配成功字符串的范围,使用result.span()可以提取其内容:
(0, 8)
match表示匹配成功的字符串内容,使用result.group()可以提取其内容:
10471204
目标:可以是数字或字母或_,不能以数字开头,用户名长度必须6位以上。
表达式:
username = "admin_002"
result = re.search("^[a-zA-Z]\w{5,}$", username)
print(result)
对应说明:
注:此时使用的是search函数,且题中要求从头开始匹配至结尾,所以需要在开头结尾添加”^”与”$”。
“^”:表示从字符串开头开始匹配。
“$”: 表示要一直匹配到结尾。
“[a-zA-Z]”:表示不能以数字开头,所以只能以大小写字母开头。
“\w”:表示匹配用户名可以是数字或字母或_。
“{5,}”:用户名长度必须6位以上,所以写入{5,},即将前一个模式匹配五次以上,而并没有小于长度的限制,所以只写{5,}即可。
输出结果:
span表示匹配成功字符串的范围,使用result.span()可以提取其内容:
(0, 9)
match表示匹配成功的字符串内容,使用result.group()可以提取其内容:
admin_002
特别注意的是,当正则表达式中有转义字符时,需要在正则表达式前添加r。
目标:找到所有py文件
表达式:
msg = "aa.py ab.txt bb.py kk.png uu.py apyb.txt"
result = re.findall(r"\w+\.py\b", msg)
print(result)
对应说明:
注:因为要寻找所有符合条件的文件,所以需要使用findall函数
“\b”:为表示找开头或结尾为某字符的字符串,所以在.py后面添加\b。
“\w”:表示匹配的字符串可以是数字或字母或_。
“+”:表示文件名长度可以任意。
”r”:其中”\b”有转义的意思,所以要在整个字符串前加”r”。且”.” 在正则中有寻找任意字符串的意思,所以要加转义字符。
若不加”r”,则需要在其前加”\”,即re.findall("\w*\\.py\\b", msg)
输出结果:
['aa.py', 'bb.py', 'uu.py']
在爬虫中通常需要使用分组正则来提取想要的内容,再使用group()进行输出。
示例1:
目标:要求提取标签内的内容,即”hello”。
表达式:
msg1 = "
result = re.match(r"<\w+>(.+)\w+>", msg1)
print(result)
print(result.group(1))
对应说明:
在正则表达式中,每一个()里的内容就是一组,如例4中”(.+)”中的”.+”即为一组。
”.+”:表示提取的内容可以是除空格外的任何字符,且长度>=1。
“\w”:表示匹配的字符串可以是数字或字母或_。
”r”: 当正则表达式中有转义字符时,需要在正则表达式前添加”r”。
输出结果:
使用print(result.group(1))可以在控制台得到输出内容:
hello
当标签过多时可以将标签也分组,如msg = "
1、number:使用\1,\2的方式进行引用。
表达式:
result = re.match(r"<(\w+)><(\w+)>(.+)\2>\1>$", msg)
print(result)
print(result.group(1))
print(result.group(2))
print(result.group(3))
对应说明:
”.+”:表示提取的内容可以是除空格外的任何字符,且长度>=1。
“\w”:表示匹配的字符串可以是数字或字母或_。
“$”: 表示要一直匹配到结尾。
”r”: 当正则表达式中有转义字符时,需要在正则表达式前添加”r”。
“\1”:表示引用前面第一个括号内的内容
“\2”:表示引用前面第二个括号内的内容。
输出结果:
hello