Python网络爬虫及正则表达式使用详解

Python网络爬虫及正则表达式使用详解


微信关注公众号:夜寒信息
致力于为每一位用户免费提供更优质技术帮助与资源供给,感谢支持!



  相信大家都听说过正则表达式及其神奇的用法,正则表达式是用来简洁表达一组字符串的表达式,下面我们来介绍它的用法。

假设有如下的一组字符串,它由’PY’构成,首字母为P后续为一个或无穷多个Y:

PY
PYY
PYYY
PYYYY
...
PYYYYY...

我们知道这组字符串的规律,到我们无法列举出所有的字符串,而这组字符串用正则表达式表达却只需要一句:

PY+

又例如我们有一组字符串,‘PY’开头,后续存在不多于10个字符,其中不包含’P’和’Y’:

PYABC
PYABCD
...

这样的字符串组合为有穷个,我们可以枚举出来,但会很繁琐。到我们可以使用一句正则表达式代替:

PY[^PY]{0,10}

是不是觉得很神奇呢?
  正则表达式是一组字符串的表达框架,能显示出字符串的特征。像我们之前举的两个例子==PY+PY[ ^PY]{0,10}==都是符合正则表达式语法的一串字符串。我们可以这么理解,我们所写出的正则表达式,是按照字符串规律总结出的一串字符串,而需要利用它则需要编译,即如下语句:

p = re.compile(regex)	#regex为符合正则表达式语法的字符串

下面我们便来学习正则表达式的语法吧!

正则表达式语法操作符

.
表示任何单个字符

[ ]
字符集,对单个字符给出取值范围,例:
[abc]表示a、b、c,而 [a-z] 表示 az单个字符

[ ^ ]
非字符集,对单个字符给出排除范围,例:
[ ^abc ] 表示非abc的单个字符

*
前一个字符0次或无限次扩展,例:
abc表示ab、abc、abcc、sbccc*等

+
前一个字符1次或无限次扩展,例:
abc+表示abc、abcc、sbccc

?
前一个字符0次或1次扩展,例:
abc?表示ab、abc

|
左右表达式任意一个,例:
abc|def表示abc、def

{m}
扩展前一个字符m次,例:
ab{2}c表示abbc

{m,n)
扩展前一个字符m至n次(含n),例:
ab{1,2}c表示abc、abcc

^
匹配字符串开头,例:
^abc表示abc且在一个字符串的开头

$
匹配字符串结尾,例:
abc $表示abc且在一个字符串的结尾

( )
分组标记,内部只能使用|操作符,例:
(abc)表示abc(abc|def)表示abc、def

\d
数字,等价于**[0-9]**

\w
单词字符,等价于**[A-Za-z0-9]**

上面这些都是最基本且常用的操作符,为了加深理解,我们举一些例子:

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

Re库的基本使用

  我们只要使用import re便可以使用Re库。正则表达式常用raw string类型(原生字符串类型)。原生字符串,就是字符串内的转义符不会被当作转义符,而是会当作字符串的一部分。例如 raw string 类型中’D:\text’便可以表示文件地址,而string类型则需要’D:\text’才能表达。

Re库的主要功能函数

re.search(pattern, string, flags)
在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象
**pattern:**正则表达式的字符串或原生字符串表示
**string:**待匹配字符串
**flags:**正则表达式使用是的控制标记

flags的常用标记:
**re.I:**忽略正则表达式的大小写,[A-Z]能够匹配小写字符
**re.M:正则表达式中的^**操作符能够将给定的字符串的每行当作匹配开始
**re.S:**正则表达式中的.操作符能够匹配所有字符,默认匹配除换行外的所有字符

下面给个例子:

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

	
100081

我们看到,search函数匹配出了100081

re.match(pattern, string, flags)
从一个字符串的开始位置起匹配正则表达式,返回match对象
**pattern:**正则表达式的字符串或原生字符串表示
**string:**待匹配字符串
**flags:**正则表达式使用是的控制标记,标记同上介绍
下面举个例子:

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

	
>>> match.group(0)
Traceback (most recent call last):
  File "<pyshell#10>", line 1, in <module>
    match.group(0)
AttributeError: 'NoneType' object has no attribute 'group'
>>> print(match)
None

因为他是从头匹配的,我们可以看出它的匹配结果报错,显示匹配结果为空,而若将要它匹配出结果则需要改变字符串参数:

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

'100081'

re.findall(pattern, string, flags)
搜做字符串,以列表类型返回全部能匹配的子串
**pattern:**正则表达式的字符串或原生字符串表示
**string:**待匹配字符串
**flags:**正则表达式使用是的控制标记,标记同上介绍
下面举个例子:

>>> ls = re.findall(r'[1-9]\d{5}', 'BIT 100081 TSU 100084')
>>> ls
['100081', '100084']

我们可以看到,它返回了一个列表里面包含了所有匹配结果。

re.split(pattern, string, maxsplit, flags)
将一个字符串按照正则表达式匹配结果进行分割,返回列表类型
**pattern:**正则表达式的字符串或原生字符串表示
**string:**待匹配字符串
**maxsplit:**最大分割数,剩余部分作为最后一个元素输出
**flags:**正则表达式使用是的控制标记,标记同上介绍
下面举个例子:

>>> re.split(r'[1-9]\d{5}', 'BIT 100081 TSU 100084')
['BIT ', ' TSU ', '']

我们可以看到,返回了一个列表包含了所有去除匹配结果后,分割后的字符串,下面我们来添加上最大分割数:

>>> re.split(r'[1-9]\d{5}', 'BIT 100081 TSU 100084',1)
['BIT ', ' TSU 100084']

我们可以看到,在匹配到第一个字符串后,将前一部分分隔出来后,将去除将匹配结果后的所有字符标为一个字符串

re.finditer(pattern, string, flags)
搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素是match对象
**pattern:**正则表达式的字符串或原生字符串表示
**string:**待匹配字符串
**flags:**正则表达式使用是的控制标记,标记同上介绍
下面举个例子:

>>> for m in re.finditer(r'[1-9]\d{5}', 'BIT 100081 TSU 100084'):
	if m:
		print(m.group(0))

		
100081
100084

我们看到,可以迭代的处理所有匹配到的结果。

re.sub(pattern, repl, string, count, flags)
在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串
**pattern:**正则表达式的字符串或原生字符串表示
**repl:**替换匹配字符串的字符串
**string:**待匹配字符串
**count:**匹配的最大替换次数
**flags:**正则表达式使用是的控制标记,标记同上介绍
下面举个例子:

>>> re.sub(r'[1-9]\d{5}','夜寒信息', 'BIT 100081 TSU 100084')
'BIT 夜寒信息 TSU 夜寒信息'

我们可以看到,匹配到的结果被替换为微信公众号的名称’夜寒信息’

Re库的等加用法

  我们以上介绍的方法都是一次性操作,例如match = re.search(r'[1-9]\d{5}', 'BIT 100081')而我们可以使用面向对象的方式使用compile函数编译后再使用,这样可以多次重复使用已约定的正则表达式,需要以下两步:

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

我们可以正常的使用函数的参数,注意无需添加正则表达式参数,例如:
原式:

>>> re.split(r'[1-9]\d{5}', 'BIT 100081 TSU 100084',1)
['BIT ', ' TSU 100084']

面向对象:

>>> pat = re.compile(r'[1-9]\d{5}')
>>> rat = pat.split('BIT 100081 TSU 100084',1)
>>> rat
['BIT ', ' TSU 100084']
Re库的Match对象

match对象中存放着匹配的所有结果,下面对他介绍。

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

	
100081
>>> type(match)
<class 're.Match'>

我们可以看到,match为正则表达式的Match类型,他有几个属性:
.string
待匹配文本

.re
匹配时使用的pattern对象(正则表达式)

.pos
正则表达式搜索文本的开始位置

.endpos
正则表达式搜索文本的结束位置

它还有一些方法:
.group()
获得匹配后的字符串

.start()
匹配字符串在原始字符串的开始位置

.end()
匹配字符串在原始字符串的结束位置

.span()
返回起始结束位置的元组**(.start(), .end())**

Re库的贪婪匹配和最小匹配

Re库默认采用贪婪匹配,即输出匹配最长的字符串,例如:

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

我们看出,本来可以匹配出’PYAN’,‘PYANBN’,‘PYANBNCN’,'PYANBNCNDN’四种结果,但我们不加约束则默认匹配最长字符串。
若要输出最小匹配则需要将正则表达式变为'PY.*?N',例如:

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



若有问题请关注微信公众号"夜寒信息"
  


微信关注公众号:夜寒信息
致力于为每一位用户免费提供更优质技术帮助与资源供给,感谢支持!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值