数据提取-正则表达式基本使用

正则表达式

正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”))操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式是一种文本模式,模式描述在搜索文本时要匹配的一个或多个字符串。

常用的特殊字符

模式 描述
^ 匹配字符串的开头
$ 匹配字符串的末尾。
. 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
[…] 用来表示一组字符,单独列出:[amk] 匹配 ‘a’,‘m’或’k’
[^…] 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。
re* 匹配0个或多个的表达式。
re+ 匹配1个或多个的表达式。
re? 匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
re{n} 精确匹配 n 个前面表达式。例如, o{2} 不能匹配 “Bob” 中的 “o”,但是能匹配 “food” 中的两个 o。
re{n,} 匹配 n 个前面表达式。例如, o{2,} 不能匹配"Bob"中的"o",但能匹配 "foooood"中的所有 o。“o{1,}” 等价于 “o+”。“o{0,}” 则等价于 “o*”。
re{ n, m} 匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式
a | b 匹配a或b
(re) 匹配括号内的表达式,也表示一个组
\w 匹配字母数字及下划线
\W 匹配非字母数字及下划线
\s 匹配任意空白字符,等价于 [\t\n\r\f].
\S 匹配任意非空字符
\d 匹配任意数字,等价于 [0-9].
\D 匹配任意非数字
\b 匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b’ 可以匹配"never" 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。
\B 匹配非单词边界。‘er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。
\1 匹配第1个分组的内容。

常用的函数

函数 描述
re.match(pattern, string, flags=0) 从字符串起始位置开始匹配,如果匹配失败直接返回none
re.search(pattern, string, flags=0) 扫描整个字符串并返回第一个成功的匹配
re.findall(pattern, string, flags=0) 找出所有满足条件的,返回一个列表
re.sub(pattern, repl, string, count=0, flags=0) 用来替换字符串
re.compile(pattern[, flags]) 用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。
re.split(pattern, string[, maxsplit=0, flags=0]) 使用正则来分割字符串

分组

在正则表达式中,可以对过滤到的字符串进行分组,分组使用圆括号的方式

  • group:和group(0)等价,返回的是满足条件的字符串
  • groups:返回的是里面的子组,索引从1开始
  • group(1):返回的是第一个子组

爬取古诗词文网的re应用示例

import re
import requests

url = "https://www.gushiwen.org/"
headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
}
r = requests.get(url,headers=headers)
text = r.text



title = re.findall(r'<a style="font-size:18px; line-height:22px; height:22px;".*?<b>(.*?)</b>',text,re.DOTALL)
dynasty = re.findall(r'<p class="source".*?<a.*?target="_blank">(.*?)</a>.*?<a.*?target="_blank">(.*?)</a>',text,re.DOTALL)
contents = re.findall(r'<div class="contson".*?>(.*?)</div>',text,re.DOTALL)


print("诗:\n",title)
print("朝代,诗人:\n",dynasty)
print("诗句:\n")
for x in contents:
    content = re.sub(r'<.*?>','',x).strip()
    print(content)

运行结果

古诗文网站的部分示例代码
数据提取-正则表达式基本使用

古诗文网页部分源码

</div>
<p><a style="font-size:18px; line-height:22px; height:22px;" href="https://so.gushiwen.org/shiwenv_a6e94e8938d4.aspx" target="_blank"><b>落花时·夕阳谁唤下楼梯</b></a></p>
<p class="source"><a href="/shiwen/default.aspx?cstr=%e6%b8%85%e4%bb%a3" target="_blank">清代</a><span></span><a href="https://so.gushiwen.org/search.aspx?value=%e7%ba%b3%e5%85%b0%e6%80%a7%e5%be%b7" target="_blank">纳兰性德</a></p>
<div class="contson" id="contsona6e94e8938d4">
夕阳谁唤下楼梯,一握香荑。回头忍笑阶前立,总无语,也依依。<br />笺书直恁无凭据,休说相思。劝伊好向红窗醉,须莫及,落花时。
</div>

参考链接 :