正则表达式
贪婪与非贪婪
使用.*的时候,会尽可能的匹配更多的字符,导致有时候取到的字符并不是我们想要的。这就是贪婪模式。
如以下代买,想要获取content内的数字1234567
import re
content = 'Hello 1234567 World_This is a Regex Demo'
result = re.match('^He.*(\d+).*Demo$', content)
print(result)
print(result.group(1))
--------------------------------------------------
<re.Match object; span=(0, 40), match='Hello 1234567 World_This is a Regex Demo'>
7
结果我们只能拿到7,是因为 .* 的贪婪模式,尽可能的匹配字符,所以把123456也匹配进 .* 了。
要解决这个问题只需要把 .* 改为 .*? ,这样就变成了尽可能的少匹配字符。
import re
content = 'Hello 1234567 World_This is a Regex Demo'
result = re.match('^He.*?(\d+).*?Demo$', content)
print(result)
print(result.group(1))
---------------------------------------------------
<re.Match object; span=(0, 40), match='Hello 1234567 World_This is a Regex Demo'>
1234567
方法:
- match()
match():从传入的字符串的开头开始匹配正则表达式,如果匹配就返回匹配结果,如果不匹配就返回None。
# match()从字符串的开头开始匹配
import re
content = 'Hello 123 4567 World_This is a Regex Demo'
print(len(content))
# Hello开头,匹配空格,匹配三个数字,匹配空格,匹配4个数字,匹配一个单词在十个字符以内
result = re.match('^Hello\s\d\d\d\s\d{4}\s\w{10}', content)
print(result)
# group()方法输出匹配到的内容
print(result.group())
# span()方法可以输出匹配的范围
print(result.span())
- search()
search():扫描整个字符串,匹配 第一个 符合正则表达式的字符串,并且返回匹配的字符串。
# search()扫描整个字符串,返回第一个成功匹配的结果,只是第一个
import re
content = 'Extra stings Hello 1234567 World_This is a Regex Demo Extra stings'
result = re.search('Hello.*?(\d+).*?Demo', content)
print(result)
print(result.group(1))
- findall()
findall():扫描整个字符串,匹配所有符合正则表达式的字符串,返回一个包含匹配字符串的 元组列表 。
- sub()
sub():扫描整个字符串,替换符合正则表达式的内容,返回一个字符串。
# sub()替换字符串中的匹配正则表达式的所有字符
import re
content = '54aK54yr5oiR54ix5L2g'
result = re.sub('\d+', '', content)
print(result)
- compile()
compile():将正则表达式字符串编译成正则表达式对象。
# compile()方法可以将正则字符串编译成正则表达式对象
import re
content1 = '2016-12-15 12:00'
content2 = '2016-12-17 12:55'
content3 = '2016-12-22 13:21'
pattern = re.compile('.{5}$')
result1 = re.sub(pattern, '', content1)
result2 = re.sub(pattern, '', content2)
result3 = re.sub(pattern, '', content3)
print(result1, result2, result3)
猫眼电影排名前100的电影:
import requests
import re
import json
from requests.exceptions import RequestException
import time
def get_one_page(url):
try:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36'
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
return response.text
return None
except RequestException:
return None
def parse_one_page(html):
pattern = re.compile(
'<dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)".*?name.*?a.*?>(.*?)</a>.*?star.*?>(.*?)</p>.*?releasetime.*?>(.*?)</p>.*?integer.*?>(.*?)</i>.*?fraction.*?>(.*?)</i>.*?</dd>',
re.S)
items = re.findall(pattern, html)
for item in items:
# yield生成迭代器,并且返回当前循环的一项结果
yield {
'index': item[0],
'image': item[1],
'title': item[2].strip(),
'actor': item[3].strip()[3:] if len(item[3]) > 3 else '',
'time': item[4].strip()[5:] if len(item[4]) > 5 else '',
'score': item[5].strip() + item[6].strip()
}
def write_to_file(content):
with open('result.txt', 'a', encoding='utf-8') as f:
print(type(json.dumps(content)))
f.write(json.dumps(content, ensure_ascii=False) + '\n')
def main(offset):
url = 'http://maoyan.com/board/4?offset=' + str(offset)
html = get_one_page(url)
my_dict = parse_one_page(html)
for item in my_dict:
print(item)
write_to_file(item)
if __name__ == '__main__':
for i in range(10):
main(offset=i*10)
time.sleep(1)