正则表达式与re模块
字符匹配
匹配单个字符
字符 | 匹配 |
---|---|
. | 匹配任意字符(\n除外) |
[ ] | 匹配中括号中的某一项 |
\d | 匹配数字 |
\D | 匹配非数字 |
\s | 匹配空白字符 |
\S | 匹配非空白字符 |
\w | 匹配a-z和A-Z以及0-9和_ |
\W | 与\w相反 |
匹配多个字符
字符 | 匹配 |
---|---|
* | 匹配前一个字符0次或无限次 |
+ | 匹配前一个字符1次或无限次 |
? | 匹配前一个字符0次或1次 |
{m} | 匹配m个字符 |
{m,n} | 匹配m-n个字符 |
*? | +? | ?? | 匹配模式变为非贪婪 |
开始结束和或语法
字符 | 匹配 |
---|---|
^ | 匹配字符串开头 |
$ | 匹配字符串结尾 |
| | 匹配 | 两边的任意一个 |
转义字符和原生字符串
# Python中的转义字符:
# raw
# text = r"hello\nworld"
# print(text)
# 正则表达式中的转义字符:
# text = "apple price is $99,range price is $88"
# result = re.findall("\$\d+",text)
# print(result)
# 原生字符串和正则表达式:
# 正则表达式的字符串解析规则:
# 1. 先把这个字符串放在Python语言层面进行解析。
# 2. 把Python语言层面解析的结果再放到正则表达式层间进行解析。
text = "\cba c"
# result = re.match("\\\\c",text) # \\\\c =(Python语言层面)> \\c =(正则表达式层面)> \c
result = re.match(r"\\c",text) # \\c =(正则表达式层面)> \c
print(result.group())
分组
在正则表达式中,可以对过滤到的字符串进行分组。分组使用圆括号的方式
group:和group(0)是等价的,返回的是整个满足条件的字符串。
groups:返回的是里面的子组。索引从1开始。
group(1):返回的是第一个子组,可以传入多个。
text = "apple price is $99,orange price is $88"
result = re.search('.+(\$\d+).+(\$\d+)',text)
print(result.groups())
# group()/group(0):匹配整个分组
# group(1):匹配第一个分组
# group(2):匹配第二个分组
# groups():获取所有的分组
re中常用的函数
re.match
尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就
返回none。
text = "1abc+"
result = re.match('\w{1,3}',text)
print(result.group())
re.search
扫描整个字符串并返回第一个成功的匹配。
text = "apple price is 34.56"
result = re.search(r"""
\d+ # 整数部分
\.? # 小数点
\d* # 小数部分
""",text,re.VERBOSE)
print(result.group())
re.compile
用于编译正则表达式,生成一个正则表达式( Pattern )对象
# compile:编译正则表达式
text = "apple price is 34.56"
r = re.compile(r"""
\d+ # 整数部分
\.? # 小数点
\d* # 小数部分
""",re.VERBOSE)
result = re.search(r,text)
print(result.group())
re.findall
在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配
的,则返回空列表
# findall:查找所有满足条件的
text = "apple price is $99,orange price is $88"
result = re.findall(r'\$\d+',text)
print(result)
re.sub
用来替换字符串。将匹配到的字符串替换为其他字符串。
# sub:根据规则替换其他字符串
text = "nihao zhongguo,hello world"
# new_text = text.replace(" ","\n")
new_text = re.sub(r' |,','\n',text) # 把空格和逗号替换成\n
print(new_text)
re.split
使用正则表达式来分割字符串
# split:根据规则分割字符串
text = "nihao zhongguo,hello world"
result = re.split(r' |,',text)
print(result)
常用函数的参数
re.DOTALL
配合.使用,使用.也匹配\n
re.S
与re.DOTALL一样
re.VERBOSE
给正则表达式加注释,可采用多行方式书写
注:多个参数一起使用需用|分隔,如:re.DOTALL|re.VERBOSE
示例
赶集网爬虫
import requests
import re
def parse_page(page_url):
print(page_url)
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
}
resp = requests.get(page_url,headers=headers)
text = resp.text
houses = re.findall(r"""
<div.+?ershoufang-list".+?<a.+?js-title.+?>(.+?)</a> # 获取房源的标题
.+?<dd.+?dd-item.+?<span>(.+?)</span> # 获取房源的户型
.+?<span.+?<span>(.+?)</span> # 获取房源的面积
.+?<div.+?price.+?<span.+?>(.+?)</span> # 获取房源的价格
""",text,re.VERBOSE|re.DOTALL)
for house in houses:
print(house)
def main():
base_url = "http://cs.ganji.com/zufang/pn{}/"
for x in range(1,11):
page_url = base_url.format(x)
parse_page(page_url)
break
if __name__ == '__main__':
main()