手机版

基于零编写python爬虫的工件正则表达式

时间:2021-09-09 来源:互联网 编辑:宝哥软件园 浏览:

接下来,我将使用白起作为爬行动物的一个小例子。但在此之前,我们应该详细梳理一下Python中的正则表达式。Python爬虫中的正则表达式就像老师骂人时使用的花名册,是必不可少的法宝。

一、正则表达式的基础1.1。概念介绍

正则表达式是处理字符串的强大工具,它不是Python的一部分。其他编程语言也有正则表达式的概念,唯一不同的是不同的编程语言有不同的语法数字。它有自己独特的语法和独立的处理引擎。在提供正则表达式的语言中,正则表达式的语法是相同的。下图显示了使用正则表达式进行匹配的过程:

正则表达式的近似匹配过程如下:1 .依次将表达式与文本中的字符进行比较;2.如果每个字符都能匹配,则匹配成功;一旦存在匹配不成功的字符,匹配就会失败。3.如果表达式中有量词或边界,过程会略有不同。

下图列出了Python支持的正则表达式元字符和语法:

1.2.量词的贪婪模式和非贪婪模式

正则表达式通常用于在文本中查找匹配的字符串。贪婪模式,总是尽量匹配尽可能多的字符;相比之下,非贪婪模式总是试图匹配尽可能少的字符。Python中的量词默认是贪婪的。例如,如果使用正则表达式“ab*”来查找“abbbc”,将会找到“abbb”。如果你使用非贪婪量词“ab*?”,会找到‘a’。

1.3.反斜杠的问题

像大多数编程语言一样,正则表达式使用“\”作为转义字符,这可能会导致反斜杠问题。如果需要匹配文本中的字符“\”,那么在用编程语言表示的正则表达式中将需要四个反斜杠“\ \ \”:第一个和第三个用于转义编程语言中的第二个和第四个反斜杠,将它们转换为两个反斜杠\ \然后在正则表达式中将它们转义为一个反斜杠以匹配反斜杠\。这显然很麻烦。Python中的原生字符串很好地解决了这个问题。本例中的正则表达式可以用r'\\ '表示。类似地,与数字匹配的“\\d”可以写成“r”\ d”。有了原生字符串,妈妈再也不用担心我的反斜杠问题了~

第二,引入re模块

2.1.编制

Python通过re模块提供对正则表达式的支持。使用re的一般步骤是:步骤1:首先,将正则表达式的字符串形式编译成Pattern实例。步骤2:然后使用模式实例来处理文本并获得匹配结果(匹配实例)。第三步:最后,使用Match实例获取信息并执行其他操作。让我们创建一个新的re01.py来测试re的应用:

复制代码如下:# -*- coding: utf-8 -*- #一个简单的re实例,匹配字符串#中的hello字符串,导入re模块import re #将正则表达式编译成Pattern对象。请注意,hello前的r表示“原生字符串”Pattern=re.compile(r'hello') #使用Pattern匹配文本并获得匹配结果。如果无法匹配,它将返回none match1=pattern。match ('hello world!)match 2=pattern . match(' helloo world!)match 3=pattern . match(' helllo world!)#如果Match1匹配成功,如果Match1: #使用match获取分组信息printmatch1.group()否则: print' match1匹配失败!#如果Match2匹配成功,如果Match2: #使用match获取分组信息printmatch2.group()否则: print' match2匹配失败!#如果Match3匹配成功,ifMatch: #使用match获取分组信息print match 3 . group()else 3360 print ' match 3匹配失败!'

您可以看到控制台输出三个匹配结果:

让我们具体看看代码中的关键方法。Re。编译(strPattern [,flag]) :该方法是Pattern类的工厂方法,用于将字符串形式的正则表达式编译成模式对象。第二个参数标志是匹配模式,该值可以用按位or运算符“|”表示,如re。我| re。m此外,还可以在正则表达式字符串中指定模式,比如re.compile('pattern ',re。我| re。m)并重新编译('(?im)pattern’)是等效的。可选值为:re。I(ignorrecase):忽略大小写(括号内完整书写,下同)re。M (MULTILINE):多线模式,改变“”和“$”的行为(见上图)re。S (DOTALL):更改“.”的行为re。l(拼写:LOCALE):使预定的字符类\w \W \b \B \s \S依赖于当前的locale re。u(拼写:UNICODE):使预定的字符类\ w \ w \ b \ s \。在这种模式下,正则表达式可以是多行的,空白字符可以忽略,并且可以添加注释。

以下两个正则表达式是等价的:

复制代码如下:# -*- coding: utf-8 -*- #两个等价的re匹配,匹配一个十进制导入re a=re.compile(r ' ' \ d #整数部分\。#小数点\ d * #某些小数位数''',re。X) b=重新编译(r'\d \。\ d * ')match 11=a . match(' 3.1415 ')Match 12=a . Match(' 33 ')Match 21=b . Match(' 3.1415 ')Match 22=b . Match(' 33 ')如果match11: #使用Match获取分组信息printMatch11.group()否则: print u' match11不是小数' ifmatch123360 #使用Match获取分组信息print Match 12 . group()else 33336

Re提供了许多模块化的方法来完成正则表达式的功能。这些方法可以被模式实例的相应方法替换。唯一的优点是一行re.compile()代码更少,但是编译后的Pattern对象不能同时重用。这些方法将在Pattern类的实例方法部分一起介绍。例如,开头的hello实例可以缩写为:

复制的代码代码如下:# -*- coding: utf-8 -*- #一个简单的re实例,它匹配hello字符串import re m=re.match (r' hello ',' hello world!')打印m.group()

re模块还提供了一个方法escape(string),用于转换正则表达式元字符,如*//?在前面添加转义字符并返回

2.2.比赛

Match对象是Match的结果,它包含了很多关于这个匹配的信息。您可以使用Match提供的可读属性或方法来获取此信息。属性:string:匹配时使用的文本。Re:匹配时使用的模式对象。Pos:文本中正则表达式开始搜索的索引。该值与具有相同名称的Pattern.match()和Pattern.seach()方法的参数相同。Endpos:文本中结束搜索的正则表达式的索引。该值与具有相同名称的Pattern.match()和Pattern.seach()方法的参数相同。Lastindex:文本中最后捕获的数据包的索引。如果没有捕获到数据包,则为无。Lastgroup:上次捕获的数据包的别名。如果此数据包没有别名或没有捕获的数据包,它将为无。方法:group([group1,…]):获取一个或多个被group截获的字符串;当指定多个参数时,它们将作为元组返回。Group1可以使用数字或别名;数字0表示整个匹配的子字符串;未填写参数时,返回组(0);不拦截字符串的组返回无;多次截取的组返回最后截取的子串。group([default]):以元组的形式返回所有组截获的字符串。相当于主叫组(1,2,…最后)。Default表示未截取字符串的组被该值替换,默认值为None。Groupdict([default]):返回字典,以别名组的别名作为关键字,以该组截获的子字符串作为值。不包括没有别名的组。Default和上面的意思一样。Start([group]):返回字符串中指定组截取的子字符串的起始索引(子字符串第一个字符的索引)。组默认值为0。End([group]):返回字符串中指定组截取的子字符串的结束索引(子字符串最后一个字符的索引1)。组默认值为0。Span([group]):返回(开始(group),结束(group))。展开(模板):将匹配的分组替换到模板中并返回。您可以在模板中使用\id或\gid或\gname引用分组,但不能使用数字0。\id和\gid是等效的;但是,10将被视为第10组。如果要在\1后表示字符“0”,只能使用\g10。让我们使用py实例来输出所有内容,以加深我们的理解:

复制的代码代码如下:# -*- coding: utf-8 -*- #一个简单的匹配实例import re #匹配以下内容:单词空白单词任意字符m=re.match(r'(\w) (\w)(?Psign。*)’,‘你好世界!’)print 'm.string: ',m.string print 'm.re: ',m . re print ' m . poss : ',m . pos print ' m . end poss : ',m.endpos print 'm.lastindex: ',m . last index print ' m . last group : ',m . last group print ' m.group(): ',m.group() print 'm.group(1,2)3: ',m . group# m.re: _sre。0x016 E1 a 38 # m . poss : 0 # m . end poss : 12 # m . last index : 3 # m . last group :符号# m.group(1,2): ('hello ',' world') # m.groups(): ('hello ',' world ','!)# m . group dict(): { ' sign ' : '!} # m . start(2): 6 # m . end(2): 11 # m . span(2):(6,11)# m . expand(r ' \ 2 \ 1 \ 3 '): world hello!

2.3.Patternpattern对象是一个编译好的正则表达式,可以通过pattern提供的一系列方法来匹配和搜索文本。模式不能直接实例化,必须由re.compile()构造,这是re.compile()返回的对象。Pattern为获取表达式信息提供了几个可读的属性:pattern:用于编译的表达式字符串。编译标志:时使用的匹配模式。数字形式。Groups:表达式中的组数。Groupindex:字典,其关键字是表达式中带有别名的组的别名,其值是对应于该组的数字。不包括没有别名的组。您可以使用以下示例来查看模式的属性:

复制代码如下:# -*- coding: utf-8 -*- #一个简单的模式实例导入re p=re.compile(r'(\w) (\w)(?Psign。*)’,re。DOTALL)打印“p.pattern n :”,p . pattern打印“p.flags:”,p.flags打印“p.groups s 3360”,p . group打印“p.groupindex:”,p . group index # # # output # # # # p . pattern n :(\ w)(\ w)(?Psign。*)# p . flag : 16 # p . group 3360 3 # p . group index : { ' sign ' : 3 }

下面重点介绍模式的示例方法及其使用。

1 .匹配

匹配(字符串[,位置[,结束位置]]) | re。match (pattern,string [,flags]):此方法将尝试从字符串的pos下标匹配模式;如果模式在最后仍然可以匹配,则返回匹配对象;如果模式在匹配过程中无法匹配,或者匹配在结束前已经到达终点,则返回无。pos和endpos的默认值分别是0和len(字符串)。Re.match()不能指定这两个参数,参数标志用于在编译模式时指定匹配模式。注意:此方法不完全匹配。当模式结束时,如果字符串中还有剩余的字符,仍然会被视为成功。为了精确匹配,可以在表达式的末尾添加一个边界匹配器“$”。让我们看一个简单的Match案例:

复制代码代码如下: #编码: UTF-8导入Re #将正则表达式编译成pattern对象:pattern=re.compile(r'hello') #将文本与Pattern匹配得到匹配结果,返回none match=pattern。Match ('hello world!)如果Match: #使用Match获取分组信息print match . group()# # # output # # # # hello

2 .搜索

Search (string [,pos [,end pos]]) | re.search (pattern,string [,flags]) :此方法用于在可以成功匹配的字符串中查找子字符串。尝试从字符串的下标位置匹配模式,如果模式在最后仍然可以匹配,则返回一个匹配对象;如果无法匹配,则在pos中添加1,然后再次尝试匹配;如果在pos=endpos之前没有匹配,将返回None。pos和endpos的默认值为0和len(字符串));分别为;Re.search()不能指定这两个参数,参数标志用于在编译模式时指定匹配的模式。那么它和火柴有什么区别呢?match()函数只检测字符串开头的re是否匹配,search()会扫描整个字符串以寻找匹配。

Match()只有在位置0匹配成功时才会返回,如果在起始位置匹配不成功,match()将不会返回任何值。例如,打印(re。匹配(' super ',' supersession ')。span())将返回(0,5) print (re。匹配(“超级”、“不可超越”)

Search()扫描整个字符串并返回第一个成功匹配的字符串,例如:print (re。搜索(' super ',' supersession ')。span())返回(0,5) print (re。搜索('超级','不可超越')。span())返回(2,7)

复制的代码如下:# -*- coding: utf-8 -*- #一个简单的搜索实例导入re #将正则表达式编译成Pattern对象pattern=re.compile(r'world') #使用search()查找匹配的子字符串,如果没有可以匹配的子字符串,将返回None #。在本例中,match()无法成功匹配match=pattern。搜索(' hello world!)如果Match: #使用Match获取分组信息print match . group()# # # output # # # # world

3.Split split(字符串[,maxsplit]) | re。split (pattern,string [,maxsplit]) :根据可以匹配的子字符串对字符串进行划分,并将其返回到列表中。Maxsplit用于指定拆分的最大数量,并不指定所有拆分。

复制代码如下:导入re p=re.compile (r' \ d ')打印p.split('一一二三四')# #输出# # # #['一','二','三','四',' ']

4.全部查找全部查找(字符串[,pos [,end pos]]) | re。find all (pattern,string [,flags]) :搜索字符串,并以列表的形式返回所有可以匹配的子字符串。

复制代码如下: import re p=re.compile(r ' \ d ')print p . find all('一一二三四四')# # # output # # # ['1 ',' 2 ',' 3 ',' 4']

5.Findierindicator(字符串[,位置[,结束位置]]) | re。Finder(模式,字符串[,标志]) :搜索字符串并返回一个迭代器,该迭代器按顺序访问每个匹配结果(匹配对象)。

复制代码如下:导入re p=re.compile (r' \ d ')为m in p . findier(' one 1 two 2 tree 344 '):打印m.group(),# #输出# # # # 1 2 3 4

6.sub

Sub (repl,string [,count]) | re。sub (pattern,repl,string [,count]) :使用repl替换字符串中每个匹配的子字符串,然后返回替换后的字符串。当repl是字符串时,可以使用\id或\gid或\gname来表示分组,但不能使用数字0。当repl是一个方法时,这个方法应该只接受一个参数(Match对象)并返回一个字符串进行替换(在返回的字符串中不能再引用分组)。计数用于指定最大替换次数。如果未指定,则进行所有替换。

复制代码如下: import re p=re.compile(r '(\ w)(\ w ')s='我说,你好世界!'打印p.sub(r'\2 \1 ',s)def func(m): return m . group(1)。title() ' ' m.group(2)。title() print p.sub(func,s) ### output ###说我,世界你好!#我说,你好世界!

7.subnsubn (repl,string [,count]) | re。sub (pattern,repl,string [,count]) :返回(sub(repl,string[,count]),替换次数)。

复制代码如下: import re p=re.compile(r '(\ w)(\ w ')s='我说,你好世界!'打印p.subn(r'\2 \1 ',s) def func(m):返回m.group(1)。title() ' ' m.group(2)。title() print p.subn(func,s) ### output ###(“说我,世界你好!”,2) #('我说,你好世界!', 2)

以上是python工件正则表达式的基本介绍,非常简单实用。我希望这对每个人都有帮助

版权声明:基于零编写python爬虫的工件正则表达式是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。