龙空技术网

Python中的正则表达式

CDA数据分析师 187

前言:

现时兄弟们对“python中正则”都比较注意,同学们都想要分析一些“python中正则”的相关文章。那么小编也在网上收集了一些有关“python中正则””的相关文章,希望姐妹们能喜欢,你们快快来学习一下吧!

一、概述

今天这篇文章带领大家学习一下Python中的正则表达式,当然了,正则表达式本身的内容就足以写好几本书了,我们这里列出的内容,仅仅是Python中常用的和基础的一些内容。

那么我们为什么要学习正则表达式呢,是因为正则表达式是为了提高复杂文本分析的效率,简单点说就是假设要自己想吃一份蛋炒饭,就需要有很多的流程,比如淘米,煮米,打蛋,炒饭等很多步骤,正则表达式呢就相当于直接到楼下的餐厅去买一份蛋炒饭去吃了,所以学会了正则表达式就会节省很多时间,让我们更快速的”吃到”我们想要的东西。

正则表达式的"祖先"可以一直上溯至对人类神经系统如何工作的早期研究。Warren McCulloch 和 Walter Pitts 这两位神经生理学家研究出一种数学方式来描述这些神经网络。

1956 年, 一位叫 Stephen Kleene 的数学家在 McCulloch 和 Pitts 早期工作的基础上,发表了一篇标题为"神经网事件的表示法"的论文,引入了正则表达式的概念。正则表达式就是用来描述他称为"正则集的代数"的表达式,因此采用"正则表达式"这个术语。

随后,发现可以将这一工作应用于使用 Ken Thompson 的计算搜索算法的一些早期研究,Ken Thompson 是 Unix 的主要发明人。正则表达式的第一个实用应用程序就是 Unix 中的 qed 编辑器。

如他们所说,剩下的就是众所周知的历史了。从那时起直至现在正则表达式都是基于文本的编辑器和搜索工具中的一个重要部分。

二、什么是正则表达式

正则表达式(Regular Expression)是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符")。

正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。

正则表达式是繁琐的,但它是强大的,学会之后的应用会让你除了提高效率外,会给你带来绝对的成就感。许多程序设计语言都支持利用正则表达式进行字符串操作。下面是一些正则表达式的语法和说明:

看了这么多的正则表达式的方法是不是感觉头很大,没事慢慢来,我们一点点的开始学习,一点点的练习早晚就可以学会的。

三、正则表达式期初

1.元字符

下面是一些常用的元字符

代码

说明

.

匹配除换行符意外的任意字符

\w

匹配字母或数字下换线或汉字

\s

匹配任意的空白符

\d

匹配数字

\b

匹配单词开始或结束

^

匹配字符串的开始

$

匹配字符串的结束

2.字符转义

如果要查找元字符本身的话,比如查找.或者的时候就出现了问题:我们没有办法指定它们,因为他们会被解释成别的意思,这个时候就得使用\来取消这些字符的特殊意义。因此,要查找.或的时候就应该使用.或*来查找,这时候可能就会有人问了,那如果我要查找\怎么办呢,同理用\就可以了。

3.重复

常用的限定符:

代码语法

说明

重复零次或更多次

重复一次或更多次

?

重复零次或一次

{n}

重复N次

{n,}

重复n次或更多次

{n,m}

重复n到m次

4.字符类

如果想要匹配没有预定义元字符集合(比如元音字母a,e,I,o,u)怎么办呢?很简单,只需要需要在方括号里面列出它们就可以了像[aeiou]就可以匹配任何一个英文元音字母,[.?!]匹配标点符号(.或?或!)

也可以通过指定一个字符返回:

像[0-9]代码的含义与\d就是完全一致的:一位数字。同理[a-z0-9A-Z]也完全等同于\w(如果只考虑英文的话)

5.分枝条件

正则表达式里的分枝条件指的是有几种规则,如果满足其中之一的任意规则都应当成匹配,具体方法是用|把不同条件分隔开。

(?0\d{2})?[- ]?\d{8}|0\d{2}[0 ]?\d{8}这个表达式匹配3位区号的电话号码,其中区号可以用小括号括起来,也可以不用,区号与本地号间可以用连字号或空格间隔,也可以没有间隔

使用分枝条件时,要注意各个条件的顺序,如果要把它改成\d{5}|\d{5}-d{4}的话,那么久只会匹配5位的邮编(以及9位邮编的前5位)。原因是匹配分枝条件时,将会从左到右地测试每个条件,如果满足某个分枝的话,就不会再管其它的条件了。

6.分组

如果想要重复多个字符,可以使用小括号来指定子表达式(也叫做分组),然后就可以指定这个子表达式的重复次数。(d{1,3}.){3}\d{1,3}是一个简单的IP地址匹配表达式。如果要理解这个表达式,请按下面的顺序分析:d{1,3}匹配1到3位的数字,(\d{1,3}.){3}匹配3位数字加上一个英语句号(这个整体也就是这个分组)重复3次,最后再加上一个1到3位的数字(\d{1,3})

注意的是IP地址中的每个数字都不能大于255,所以上面的匹配方式也会匹配到256.300.669.999这种不可能存在的IP地址,那么应该怎么才能改进呢?

7.反义

如果有时会需要查找一些不输入某个能简单定义的字符类的字符。比如想查找除了数字以外,其他任意字符都行的情况,这时候就需要用到反义,下面是一些常用的反义代码

代码

说明

\w

匹配任意不是字母,数字,下划线,汉字的字符

\s

匹配任意不是空白符的字符

\d

匹配任意非数字的字符

\b

匹配不是单词开头或结束的位置

[^x]

匹配除了x以外的任意字符

[^aeiou]

匹配除了aeiou这几个字母以外的任意字符

8.贪婪与懒惰

当正则表达式中包涵能接受重复的限定符时,通常的行为是(在使整个表达式能够得到匹配的前提下)匹配尽可能多的字符,以这个表达式为例:a.*b,他将会匹配最长的以a开始,以b结束的字符串。如果用来搜索aabab的话,它会匹配整个字符串aabab。这也被成为贪婪匹配。

有时候我们更需要懒惰匹配,也就是匹配尽可能少的字符,前面给出的限定符都可以转化为懒惰匹配模式,只要在它后面加上一个问号?,这样.*?就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。

下面是一些懒惰限定符:

代码

说明

*?

重复任意次,但尽可能少重复

+?

重复1次或更多次, 但尽可能少重复

??

重复0次货1次, 但尽可能少重复

{n,m}?

重复n次到m次, 但尽可能少重复

{n,}?

重复n次以上, 但尽可能少重复

四、Python中的re模块

Python中通过re模块提供对正则表达式的支持。使用re的一般步骤是先将正则表达式的字符串形式编译为pattern实例,然后使用pattern实例处理文本并获得匹配结果(一个match实例),最后使用match实例获得信息,进行其他操作

1.导入re模块

2.将正则表达式编译为pattern对象

3.使用pattern匹配文本,获得匹配结果,无法匹配时将返回None

4.re.compile(strPattern[,flag]):

这个方法是pattern类的工程方法,用于将字符串形式的正则表达式编译为pattern对象,第二个参数是匹配模式,去值可以使用按位或运算符’|’表示同时生效,比如re.I|re.M’

可选值有下面六种:

Re.I(re.IGNORECASE):忽略大小写(括号内是完整写法,下同)M(MULTILINE):多行模式,改变^和$的行为S(DOTALL):点任意匹配模式,改变.的行为L(LOCALE):使预定字符类\w \W \b \B \s \S取决于当前区域设定U(UNICODE):使预定字符类\w \W \b \B \s \S \d \D取决于unicode定义的字符属性X(VERBOSE):详细信息:这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释

Re提供了众多模块方法用于完成正则表达式的功能,这些方法可以使用pattern实例的相应方法替代,唯一的好处是少些了一行re.compole()代码,但同时也无法复用编译后的pattern对象,这些方法将在pattern类的实例方法一起介绍,如上面这个例子可以简写为:

5.match对象

Match对象是一次匹配的结果,包含了很多关于此次匹配的信息,可以使用match提供的可读属性或方法来获取这些信息

Match属性:

String:匹配使用的文本Re:匹配使用pattern对象Pos:文本中正则表达式开始搜索的索引,值与pattern.match()和pattern.seach()方法的同名参数相同。Endpos:文本中正则表达式结束搜索的索引,值与pattern.match()和pattern.seach()方法的同名参数相同。Lastindex:最后一个被捕获的分组在文本中的索引,如果没有被捕获的分组,将为NoneLastgroup:最后一个被捕获的分组的别名,如果这个分组没有别名或者被捕获的分组,将为None

Match方法:

group([group1,...]):

获得一个或多个分组截获的字符串;指定多个参数时将以元组形式返回。group1 可以使用编号也可以使用别名;编号0代表整个匹配的子串;不填写参数时,返回group(0) ;没有截获字符串的组返回None ;截获了多次的组返回最后一次截获的子串。

●groups(default]):

以元组形式返回全部分组截获的字符串。相当于调用group(1,2... last)。default表示没有截获字符串的组以这个值替代,默认为None。

groupdict([default]):

返回以有别名的组的别名为键、以该组截获的子串为值的字典,没有别名的组不包含在内。defalt含义同上。

●start([group]):

返回指定的组截获的子串在string中的起始索引(子串第一个字符的索引) 。group默认值为0。

●end([group):

返回指定的组截获的子串在string中的结束索引(子串最后一个字符的索引+1 ). group默认值为0。

●span([group]):

返回(start(group),end(group))。

●expand(template):

将匹配到的分组代入template中然后返回。template中可以使用\id或\g、 \g引用分组,但不能使用编号0。\id与\g是等价的;但\10将被认为是第10个分组,如果你想表达\1之后是字符'0',只能使\g0。

6.pattwern

Pattern对象是一个编号的正则表达式,通过pattern提供的一系列方法可以对文本进行匹配查找。Pattern不能直接实例化,必须使用re.compile进行()构造。Pattern提供了几个可读属性用于获取表达式的相关信息:

pattern:编译时用的表达式字符串。flags:编译时用的匹配模式。数字形式groups:表达式中分组的数量groupindex:以表达式中有别名的租的别名为键、以改组对应的编号为值的字典,没有别名的租不包含在内。

注意:在表达式前面使用’r’是用来表示字符串内部不需要进行额外的转义(原生字符串),可以避免很多无法察觉的问题。

五、re模块的方法

实例方法[\re模块方法]:

1.match(string[,pos[,endpos]])|re.match(pattern,string[,flags]):

这个方法将从string的pos下标处尝试匹配pattern;如果pattern结束时仍可匹配,则返回一个match对;如果匹配过程中pattern无法匹配,或则匹配未结束就已到达endpos,则返回None。

Pos和endpos的默认值分别为0和len(string);re.match()无法指定这两个参数,参数flags用于编译pattern时指定匹配模式。

这个方法并不是完全匹配,当pattern结束时若string还有剩余字符,仍然十位成功。想要完全匹配可以在表达式末尾加上边界匹配符$。

2.search(string[,pos[,endpos]])|re.search(pattern,string[,flags]):

这个方法用于查找字符串中可以匹配成功的子串,从string的pos下标处尝试匹配pattern,如果pattern结束时仍可匹配,则返回一个match对象;若无法匹配则将pos加1后重新尝试匹配;知道pos=endpos时无法匹配则返回None。

Pos和endpos的默认值分别为0和len(string);re.search()无法指定这两个参数,参数flags用于编译pattern时指定匹配模式。

3.split(string[,maxsplit])|re.split(pattern,string[,maxsplit])’

按照能够匹配的子串将string分割后返回列表。Maxsplit用于指定最大分隔次数,不指定将全部分隔。

4.findall(string[,pos[,endpos]])|re.findall(pattern,string[,flags]):

搜索string,以列表的形式返回全部能匹配的子串

5.finditer(string[,pos[,endpos]])|re.finditer(pattern,string[.flags]):

搜索string,返回一个顺序访问每一个匹配结果(match对象)的迭代器

6.sub(repl,string[,count])|re.sub(pattern,repl,string[,count]):

使用repl替换string中的每一个匹配的子串后返回替换的字符串。当repl是一个字符串时,可以使用\id或\g、\g引用分组,但不能使用编号0。当repl是一个方法时,这个方法应当只接受一个参数(match对象),并返回一个字符串用于替换(返回的字符串不能再引用分组)。

Count用于指定最多替换次数,不指定时全部替换。

7.subn(repl,string[,count])|re.sub(pattern,repl,string[,count]):

返回(sub(repl,string[,count]),替换次数)。

标签: #python中正则 #python中pos的含义 #pos在python中的含义