用 requests 库可以获取网页的 HTML 源码,在做爬虫时,我们需要从 HTML 源码中提取我们需要的信息,这时就用到了正则表达式。
常用正则表达式匹配规则如下:
python 的 re 库提供了整个正则表达式的实现。
1、Match
match 可以检测字符串和正则表达式是否匹配。match 从字符串起始位置开始匹配正则表达式,并返回匹配的结果,如果没有匹配结果,返回 None。使用方法如下:
import re
text = "Hello world 123 4567 python is the best language!"
regex = '[a-zA-Z]+\s[a-zA-Z]+\s\d\d\d\s\d{4}\s\w{6}.*'
result = re.match(regex, text)
print(result)
print(result.group())
print(result.span())
[a-zA-Z]表示匹配大小写字母,'+' 表示前面内容匹配1个以上,'\s'表示匹配任意非空字符,'\d'表示匹配任意数字(同[0-9]),'\w{6}'表示匹配数字、字母、下划线6个字符,'.' 表示匹配除换行外的任意字符,'*' 表示匹配0个或多个表达式,匹配输出结果如下:
<re.Match object; span=(0, 27), match='Hello world 123 4567 python'>
Hello world 123 4567 python
(0, 27)
(1)匹配目标
如果想从 match 匹配结果中提取一部分字符串,可以使用括号()将想要提取结果部分的表达式括起来,然后调用group(d)方法传入分组索引的索引号d,即可提取匹配结果,使用方法如下:
import re
text = "Hello world 123 4567 python is the best language!"
regex = '[a-zA-Z]+\s([a-zA-Z]+)\s\d\d\d\s\d{4}\s(\w{6})'
result = re.match(regex, text)
print(result)
print(result.group())
print(result.group(1))
print(result.group(2))
print(result.span())
匹配输出结果如下:
<re.Match object; span=(0, 27), match='Hello world 123 4567 python'>
Hello world 123 4567 python
world
python
(0, 27)
(2)通用匹配
比较复杂的正则表达式,对单个字符均使用相应匹配规则进行匹配,则工作量非常大且不具有灵活性。此时可以考虑使用".*","."可以匹配除换行符之外的所有字符,"*"可以不限次匹配前面规则,所以".*"可以匹配任意内容,使用该规则可以简化表达式的使用。使用方法如下:
#****************************************
# use of '.*'
#****************************************
import re
text = "Hello world 123 4567 python is the best language!"
pattern = "Hello.*"
result = re.match(pattern,text)
print(result)
print(result.group())
print(result.span())
匹配输出结果如下:
<re.Match object; span=(0, 49), match='Hello world 123 4567 python is the best language!>
Hello world 123 4567 python is the best language!
(0, 49)
(3)贪婪与非贪婪
在贪婪匹配下,".*"会匹配尽可能多的字符,而将最少数的字符留于后面规则,其匹配结果往往不是我们所需要的。使用示例如下:
import re
text = "Hello world 1234567 python is the best language!"
pattern = "Hello.*(\d+)"
result = re.match(pattern,text)
print(result)
print(result.group())
print(result.group(1))
print(result.span())
匹配输出结果如下:
<re.Match object; span=(0, 19), match='Hello world 1234567'>
Hello world 1234567
7
(0, 19)
此处,"(\d+)" 只匹配到了一个数字'7',在此之前的数字也被'.*' 规则匹配了,显然不是我们需要的。
通常,文中我们可以使用非贪婪匹配".*?"代替贪婪匹配,使用方式如下:
import re
text = "Hello world 1234567 python is the best language!"
pattern = "Hello.*?(\d+)"
result = re.match(pattern,text)
print(result)
print(result.group())
print(result.group(1))
print(result.span())
匹配结果输出如下:
<re.Match object; span=(0, 19), match='Hello world 1234567'>
Hello world 1234567
1234567
(0, 19)
显然,此处,"(\d+)" 匹配到了英文字母后面连续的所有数字'1234567'。
注:贪婪匹配是尽可能多的匹配字符,非贪婪匹配是尽可能少的匹配字符。所以在匹配的时候,字符串中间需尽量使用非贪婪匹配,字符串结尾的地方,需尽量使用非贪婪匹配。
(4)修饰符
常见匹配修饰符如下,其中,常见匹配修饰如为 re.I、re.S:
在字符串中加有换行符时,匹配规则不能匹配换行符,则上面的匹配方式可能就不能得到正确的匹配结果,比如下面示例:
import re
text = "Hello world \n1234567 python is the best language!"
pattern = "Hello.*?(\d+)"
result = re.match(pattern, text)
print(result)
print(result.group(1))
print(result.span())
匹配输出结果如下:
None
Traceback (most recent call last):
File "D:/Develop/PYTHON/Demo/Python_Study/Python3WebSpider/Regex/regex_match.py", line 47, in <module>
print(result.group(1))
AttributeError: 'NoneType' object has no attribute 'group'
在字符串中存在换行符时,可以在匹配时加上匹配修饰符 "re.S",即可进行匹配。使用方式如下:
import re
text = "Hello world \n1234567 python is the best language!"
pattern = "Hello.*?(\d+)"
result = re.match(pattern, text, re.S)
print(result)
# print(result.group())
print(result.group(1))
print(result.span())
匹配输出结果如下:
<re.Match object; span=(0, 20), match='Hello world \n1234567'>
1234567
(0, 20)
(5)转义匹配
当匹配字符串中含有与匹配规则相同的字符时,可以在字符前加 '\' 进行转义,从而进行匹配。使用方式如下:
import re
text = "www.baidu.com"
pattern = "www\.baidu\.com"
result = re.match(pattern,text)
print(result)
print(result.group())
匹配输出结果如下:
<re.Match object; span=(0, 13), match='www.baidu.com'>
www.baidu.com
后续公众号会发布系列教程,更多内容请关注公众号:程序猿学习日记