python3爬虫学习之数据提取之re

世界上的人分为两种,会正则表达式的,不会正则表达式的。

作为提取信息极为强大,也最难以掌握的,正则表达式,我属于第二类人,努力向前一种看齐,记录一下re的基本方法与使用,下个博客上实战。

以下所有代码基于此

import re

一:首先,了解匹配单个字符

说在前面,我们应该注意到,当我们用re的match方法匹配单个字符时,它会从第一个字符开始匹配,如果匹配不成功就会报错,匹配成功才能打印

1:匹配任意字符

text = "hello"
ret = re.match("he" , text)
print(ret.group())

2:英文符号“.”匹配任意字符

text = "hello"
ret = re.match("." , text)
print(ret.group())

在这里说明一点“.”无法匹配换行符

3:\d匹配任意数字,即[0-9]。\D匹配任意非数字,即[^0-9]

text = "123"
ret = re.match("\d" , text)
print(ret.group())


text = "hello"
ret = re.match("\D" , text)
print(ret.group())

4:\s匹配任意空白符("\n" , "\t" , "\r" , " ")

text = "\r \n \t"
ret = re.match("\s" , text)
print(ret.group())

5:\w匹配0-9a-zA-Z等同于[0-9a-zA-Z_],\W相反等同于[^0-9a-zA-Z_]

扫描二维码关注公众号,回复: 5840217 查看本文章
text = "01aZ_"
ret = re.match("\w" , text)
print(ret.group())

text = "+@#$%"
ret = re.match("\W" , text)
print(ret.group())

6:[ ]组合方式,只要满足[]中的任意一项即可匹配成功

text = "5"
ret = re.match("[az12345]" , text)
print(ret.group())

二:匹配多个字符

说在前面,我们应该了解到什么是正则表达式中的贪婪与非贪婪匹配

在正则表达式中,默认为贪婪匹配,即尽量多的匹配

?表示非贪婪匹配,完成最少匹配项就停止匹配

在这里举个栗子:

1:+匹配1或多个字符

text = "1465131"
ret = re.match("\d+?" , text)
print(ret.group())
res = re.match("\d+" , text)
print(res.group())

2:*匹配0或多个字符

text = "1465131"
ret = re.match("\d*" , text)
print(ret.group())

3:?匹配0或一个字符

text = "+9551"
ret = re.match("\w?" , text)
print(ret.group())

4:{m}匹配m个字符

text = "146fsd51ef3d1"
ret = re.match("\w{8}" , text)
print(ret.group())

5:{m:n}匹配m到n中间的任意个字符,默认采用贪婪匹配,即匹配尽量接近n个字符

text = "146fsd51ef3d1"
ret = re.match("\w{1,5}" , text)
print(ret.group())

三:常用匹配案例

1:匹配身份证号

我们了解到身份证号是由前17位数字加最后一位数字或者x或者X组成

text = "12345678910121314x"
ret = re.match("\d{17}[\dxX]" , text)
print(ret.group())

2:匹配163邮箱

我们了解到163邮箱有着固定的结尾,即@163.com,前面则由最少一位字母数字下划线组成

在这里补充,^表示以" "开头,$表示以" "结尾,|表示或

text = "[email protected]"
ret = re.match("\[email protected]$" , text)
print(ret.group())

3:匹配0-100包括0和100

注意,常规的0-100,不能以0开头,例如:01,021

text = "1000"
ret = re.match("\d$|[1-9]\d$|100$" , text)
print(ret.group())

我们了解到\d表示0-9,中间 | 隔开表示或,我们匹配到0-9,即个位数

[1-9]\d$,我们需要匹配两位数,两位数不能0开头,我们用[1-9]表示,个位数无限制\d表示,记得结尾$

那么三位数只有100,然后结尾$,对结尾有疑惑的可以试试不添加,实践出真知。

4:再上一个贪婪与非贪婪的案例

text = "<h1>标题<h1>"
ret = re.match("<.+?>" , text)
print(ret.group())

这里可以试试贪婪与非贪婪出来的结果有什么区别,不再上运行结果了

5:这里举一个案例说明一个重要字符串,原生字符串

text = "apple is $299"
ret = re.search("\$\d+" , text)
print(ret.group())

text = r'\n'
ret = re.match(r"\\n" , text)
print(ret.group())

第一个例子中,我们要获取的是带有美元符的价格,而$是特殊字符,故而需要转义即\$

第二个例子中,我们用到了r,那么r" "中的字符串都是原生字符串,也就是未经转义的字符串,而我们匹配时也用到了原生字符串

那么在这里推荐大家上下都不使用原生字符串,上面使用下面不使用,上面不使用下面使用来测试一下需要多少转义字符\来打印换行符

6:下面举例了解分组函数group,放在代码的注释中

text = "apple is $99 , orange is $10 , banana is $20"
ret = re.search(".*(\$\d+).*(\$\d+).*(\$\d+)" , text)
# print(ret.group())#获取整条等价于group(0)
# print(ret.group(1))#获取第一个小括号内的,即第一个价格
print(ret.groups())#获取所有子分组

7:下面举个栗子了解findall方法

text = "apple is $99 , orange is $10 , banana is $20"
ret = re.findall("\d+" , text)#返回数组
print(ret)

8:下面举个栗子了解sub替换函数

text = "apple is $99 , orange is $10 , banana is $20"
ret = re.sub("\d+" , "0" ,text)
print(ret)

9:下面举个栗子了解split分割函数

text = "ad5d4ser45a*&hUIY&b"
ret = re.split("[^a-zA-Z]",text)
print(ret)

10:下面举个栗子了解compile预编译正则表达式函数

text = "apple is 0.55"
# r = re.compile("\d+\.?\d*")
r = re.compile("""
    \d+ #表示小数点前的数 一位或多位
    \.? #表示小数点本身,有或无
    \d* #表示小数点后的数,无或有
""",re.VERBOSE)
ret = re.search(r,text)
print(ret.group())

这个函数可以把正则表达式编译后多次重复使用,提高可用性

大家在使用该函数时推荐向代码中一样使用未注释的,正则表达式理解较难,编写时可能理解,过一段时间可能就忘了,这样就提高了代码可读性

这篇文章普遍没有贴运行结果,因为正则表达式在爬虫中占有较大作用,理解和使用都很重要,一定要实践才能加深理解,也为了自己以后复习避免眼高手低不去实践。

最后,实践出真知。

猜你喜欢

转载自blog.csdn.net/s_kangkang_A/article/details/89048896
今日推荐