0
点赞
收藏
分享

微信扫一扫

正则表达式用法

糯米


2020.08.25

网络爬虫

Web spider

and information extraction

正则表达式用法_正则表达式

相信大家都听说过正则表达式及其神奇的用法

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

下面我们来介绍它的用法

1

正则表达式概述

假设有如下的一组字符串,它由’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为符合正则表达式语法的字符串


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


正则表达式用法_正则表达式_02

>>

<<

正则表达式用法_字符串_03

2

正则表达式语法操作符


01

.

表示任何单个字符

02

[]

字符集,对单个字符给出取值范围,例:

[abc]表示a、b、c,而 [a-z] 表示 a到z单个字符

03

[^]

非字符集,对单个字符给出排除范围,例:

[ ^abc ] 表示非a或b或c的单个字符

04

*

前一个字符0次或无限次扩展,例:

abc表示ab、abc、abcc、sbccc*等

05

+

前一个字符1次或无限次扩展,例:

abc+表示abc、abcc、sbccc等

06

?

前一个字符0次或1次扩展,例:

abc?表示ab、abc

07

|

左右表达式任意一个,例:

abc|def表示abc、def

08

{m}

扩展前一个字符m次,例:

ab{2}c表示abbc

09

{m,n)

扩展前一个字符m至n次(含n),例:

ab{1,2}c表示abc、abcc

10

^

匹配字符串开头,例:

^abc表示abc且在一个字符串的开头

11

$

匹配字符串结尾,例:

abc $表示abc且在一个字符串的结尾

12

()

分组标记,内部只能使用|操作符,例:

(abc)表示abc,(abc|def)表示abc、def

13

\d

数字,等价于[0-9]

14

\w

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


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

正则表达式用法_字符串_04


正则表达式用法_操作符_05


正则表达式用法_操作符_06



正则表达式用法_正则表达式_07

正则表达式用法_正则表达式_07

正则表达式用法_正则表达式_07


3

Re库的基本使用


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


01

Re


的主要功能函数

01

re.search(pattern, string, flags)

在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象

pattern:正则表达式的字符串或原生字符串表示

string:待匹配字符串

flags:正则表达式使用是的控制标记


02

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


03

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'



04

re.findall(pattern, string, flags)

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

pattern:正则表达式的字符串或原生字符串表示

string:待匹配字符串

flags:正则表达式使用是的控制标记,标记同上介绍

下面举个例子:

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

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



05

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']

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


06

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

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


07

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 夜寒信息'

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




02

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']



03

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类型,他有几个属性:


01

.string

待匹配文本

02

.re

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

03

.pos

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

04

.endpos

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

05

.group

获得匹配后的字符串

06

.start

匹配字符串在原始字符串的开始位置

07

.end

匹配字符串在原始字符串的结束位置

08

.span

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



04

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'


END

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

正则表达式用法_正则表达式_10






举报

相关推荐

0 条评论