【爬虫】6基础Python网络爬虫——Re库(MOOC学习笔记)

入门Re(正则表达式库)

Re正则表达式详解——提取页面关键信息

(1)正则表达式的概念

正则表达式:regular expression, regex, RE,是用来简洁表达一组字符串的表达式,例如:

  • 一组字符串:
    ‘PN’ ‘PYN’ ‘PYTN’ ‘PYTHN’ ‘PYTHON’
    正则表达式为:
    P(Y|YT|YTH|YTHO)?N
  • 一组字符串(无穷个):
    ‘PY’ ‘PYY’ ‘PYYY’ ‘PYYYY’ …… ‘PYYYY……’
    正则表达式为(无穷字符串组的简洁表达):
    PY+
  • 一组字符串(后续存在不多于10个字符 后续字符不能是’P’或’Y’ )
    'PYABC’√ 'PYKXYZ’×
    正则表达式为(某种特征字符串组的简洁表达):
    PY[^PY]{0,10}

Re优势:一行就是特征(模式)——一行胜千言
正则表达式是一种通用的字符串表达框架,进一步,正则表达式是一种针对字符串表达“简洁”和“特征”思想的工具,正则表达式可以用来判断某字符串的特征归属

正则表达式在文本处理中十分常用:

  • 表达文本类型的特征(病毒、入侵等)
  • 同时查找或替换一组字符串
  • 匹配字符串的全部或部分,最主要应用在字符串匹配
  • ……

如何使用?

还是看之前的这个例子:

  • 一组字符串:
    ‘PN’ ‘PYN’ ‘PYTN’ ‘PYTHN’ ‘PYTHON’
    正则表达式:
    P(Y|YT|YTH|YTHO)?N
    即regex=‘P(Y|YT|YTH|YTHO)?N’
    编译一下:p=re.compile(regex)
    可以发现原来字符串的特征就是:特征(p)

其中,编译——将符合正则表达式语法的字符串转换成正则表达式特征

(2)正则表达式的语法

正则表达式例如:P(Y|YT|YTH|YTHO)?N,可见正则表达式语法由字符和操作符构成

常用操作符如下所示:
在这里插入图片描述
在这里插入图片描述
正则表达式语法实例:

  • P(Y|YT|YTH|YTHO)?N→’PN’、‘PYN’、‘PYTN’、‘PYTHN’、‘PYTHON’
  • PYTHON+→’PYTHON’、‘PYTHONN’、‘PYTHONNN’…
  • PY[TH]ON→’PYTON’、‘PYHON’
  • PY[^TH]?ON→’PYON’、‘PYaON’、‘PYbON’、‘PYcON’…
  • PY{:3}N→’PN’、‘PYN’、‘PYYN’、‘PYYYN’…

经典正则表达式实例:

  • ^[A‐Za‐z]+$→由26个字母组成的字符串
  • ^[A‐Za‐z0‐9]+$ →由26个字母和数字组成的字符串
  • ^‐?\d+$ →整数形式的字符串
  • ^[0‐9]*[1‐9][0‐9]*$ →正整数形式的字符串
  • [1‐9]\d{5} →中国境内邮政编码,6位
  • [\u4e00‐\u9fa5] →匹配中文字符
  • \d{3}‐\d{8}|\d{4}‐\d{7}→国内电话号码,010‐68913536

匹配IP地址的正则表达式

IP地址字符串形式的正则表达式(IP地址分4段,每段0‐255)
\d+.\d+.\d+.\d+或 \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}
精确写法:
0‐99→[1‐9]?\d
100‐199→1\d{2}
200‐249→2[0‐4]\d
250‐255→25[0‐5]
所以应写为:
(([1‐9]?\d|1\d{2}|2[0‐4]\d|25[0‐5]).){3}([1‐9]?\d|1\d{2}|2[0‐4]\d|25[0‐5])

(3)Re库的基本使用

Re库是Python的标准库,主要用于字符串匹配,调用方式:

import re

正则表达式的表示类型

raw string类型(原生字符串类型),re库采用raw string类型表示正则表达式,表示为:r’text’,例如:

  • r’[1‐9]\d{5}’
  • r’\d{3}‐\d{8}|\d{4}‐\d{7}’

raw string是不包含对转义符再次转义的字符串
re库也可以采用string类型表示正则表达式,但更繁琐,例如:

  • ‘[1‐9]\d{5}’
  • ‘\d{3}‐\d{8}|\d{4}‐\d{7}’
    建议:当正则表达式包含转义符时,使用raw string

Re库主要功能函数如下所示:
在这里插入图片描述

re.search

返回match对象

re.search(pattern, string, flags=0)
  • pattern : 正则表达式的字符串或原生字符串表示
  • string : 待匹配字符串
  • flags : 正则表达式使用时的控制标记

在这里插入图片描述

import re
regex = r'[1-9]\d{5}'
string = "BIT 100081, HUBEI JINGMEN 448000."
match = re.search(regex, string)
if match:
    print(match.group(0))
    print(match.group())

结果如下:

100081
100081

re.match

从一个字符串的开始位置起匹配正则表达式,返回match对象

re.match(pattern, string, flags=0)
  • pattern : 正则表达式的字符串或原生字符串表示
  • string : 待匹配字符串
  • flags : 正则表达式使用时的控制标记
import re
regex = r'[1-9]\d{5}'
string = "BIT 100081, HUBEI JINGMEN 448000."
string2 = "100081 BIT, HUBEI JINGMEN 448000."
match = re.match(regex, string)
match2 = re.match(regex, string2)
if match:
    print('1:'+match.group(0))
if match2:
    print('2:'+match2.group())

结果如下:

2:100081

re.findall

搜索字符串,以列表类型返回全部能匹配的子串

re.findall(pattern, string, flags=0)
  • pattern : 正则表达式的字符串或原生字符串表示
  • string : 待匹配字符串
  • flags : 正则表达式使用时的控制标记
import re
regex = r'[1-9]\d{5}'
string = "BIT 100081, HUBEI JINGMEN 448000, TSINGHUA100084,0100084,01000840,1234567890123456789."
match = re.findall(regex, string)
if match:
    print(match)

结果如下:

['100081', '448000', '100084', '100084', '100084', '123456', '789012', '345678']

re.split

将一个字符串按照正则表达式匹配结果进行分割,返回列表类型

re.split(pattern, string, maxsplit=0, flags=0)
  • pattern : 正则表达式的字符串或原生字符串表示
  • string : 待匹配字符串
  • maxsplit: 最大分割数,剩余部分作为最后一个元素输出
  • flags : 正则表达式使用时的控制标记
import re
regex = r'[1-9]\d{5}'
string = "BIT 100081, HUBEI JINGMEN 448000, TSINGHUA100084,0100084,01000840,1234567890123456789."
match = re.split(regex, string)
match2 = re.split(regex, string, maxsplit=2)
print(match)
print(match2)
['BIT ', ', HUBEI JINGMEN ', ', TSINGHUA', ',0', ',0', '0,', '', '', '9.']
['BIT ', ', HUBEI JINGMEN ', ', TSINGHUA100084,0100084,01000840,1234567890123456789.']

re.finditer

搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素是match对象

re.finditer(pattern, string, flags=0)
  • pattern : 正则表达式的字符串或原生字符串表示
  • string : 待匹配字符串
  • flags : 正则表达式使用时的控制标记
import re
regex = r'[1-9]\d{5}'
string = "BIT 100081, HUBEI JINGMEN 448000, TSINGHUA100084,0100084,01000840,1234567890123456789."
for match in re.finditer(regex, string):
    if match:
        print(match.group())

结果为:

100081
448000
100084
100084
100084
123456
789012
345678

re.sub

在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串

re.sub(pattern, repl, string, count=0, flags=0)
  • pattern : 正则表达式的字符串或原生字符串表示
  • repl: 替换匹配字符串的字符串
  • string : 待匹配字符串
  • count : 匹配的最大替换次数
  • flags : 正则表达式使用时的控制标记
import re
regex = r'[1-9]\d{5}'
string = "BIT 100081, HUBEI JINGMEN 448000, TSINGHUA100084,0100084,01000840,1234567890123456789."
match = re.sub(regex, 'zipcode', string)
print(match)

结果为:

BIT zipcode, HUBEI JINGMEN zipcode, TSINGHUAzipcode,0zipcode,0zipcode0,zipcodezipcodezipcode9.

Re库的另一种等价用法

函数式用法:一次性操作:

rst = re.search(r'[1‐9]\d{5}', 'BIT 100081')

等价于面向对象用法:编译后的多次操作

pat = re.compile(r'[1‐9]\d{5}')
rst = pat.search('BIT 100081')

re.compile——将正则表达式的字符串形式编译成正则表达式对象

regex = re.compile(pattern, flags=0)
  • pattern : 正则表达式的字符串或原生字符串表示
  • flags : 正则表达式使用时的控制标记
    如:
regex = re.compile(r'[1‐9]\d{5}')

在这里插入图片描述

(4)Re库的Match对象

Match对象是一次匹配的结果,包含匹配的很多信息,例如:

>>>match = re.search(r'[1‐9]\d{5}', 'BIT 100081')
>>>if match:
	  print(match.group(0))
>>>type(match)

<class '_sre.SRE_Match'>

在这里插入图片描述
在这里插入图片描述

import re
regex = r'[1-9]\d{5}'
string = "BIT 100081, HUBEI JINGMEN 448000, TSINGHUA100084,0100084,01000840,1234567890123456789."
m = re.search(regex, string)
print(m.string)
print(m.re)
print(m.pos)
print(m.endpos)
print(m.group(0))
print(m.start())
print(m.end())
print(m.span())

结果如下:

BIT 100081, HUBEI JINGMEN 448000, TSINGHUA100084,0100084,01000840,1234567890123456789.
re.compile('[1-9]\\d{5}')
0
86
100081
4
10
(4, 10)

这个个人感觉很有用,可以配合finditer来对整个HTML进行遍历

(5)Re库的贪婪匹配和最小匹配

同时匹配长短不同的多项,返回哪一个呢?

>>>match = re.search(r'PY.*N', 'PYANBNCNDN')
>>>match.group(0)

'PYANBNCNDN'

Re库默认采用贪婪匹配,即输出匹配最长的子串

如何输出最短的子串呢?

>>>match = re.search(r'PY.*?N', 'PYANBNCNDN')
>>>match.group(0)

'PYAN'

只要长度输出可能不同的,都可以通过在操作符后增加?变成最小匹配
在这里插入图片描述

小结

正则表达式是用来简洁表达一组字符串的表达式

r'\d{3}‐\d{8}|\d{4}‐\d{7}'

re.search() = regex=re.compile() + regex.search()

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值