Python正则表达式完整指南
正则表达式处理文本就像风扫过秋叶一样。大多数编程语言都内置了对正则表达式的支持,用于表单验证、文本提取和替换等场景。爬虫系统离不开正则表达式,可以事半功倍。
在介绍正则表达式之前,我们先来看一个问题。以下文字来源于豆瓣的一个网页链接,我对内容进行了删减。问:如何提取文本中的所有电子邮件地址?
html=' ' '样式。二维码-app { display : }块;background : URL(/pics/[email protected])不重复;}/style div class=' reply-doc content ' p class=' '[email protected],谢谢/p p class=''[emailprotected]请/p/div p class=' '[email protected]br/谢谢/p ' '。如果你没有接触过正则表达式,我认为你对此无能为力。似乎你想不出更好的方法来处理它而不正规化。然而,让我们暂时把这个问题放在一边,等到你学完正则表达式。
字符串的表示形式
Python字符串有几种表达形式,以U开头的字符串称为Unicode字符串,这超出了本文的范围。此外,你应该已经看到了这两种写作方式:
Foo='hello' bar=r'hello '前者是常规字符串,而后者以原始字符串开头。两者有什么区别?因为在上面的例子中,它们都是由普通文本字符组成的字符串,这里没有区别,这可以在下面证明
Foo是barTrue foo==barTrue但是如果字符串包含特殊字符会怎么样呢?我们再举一个例子:
Foo=' \ n' bar=r' \ n' foo,len (foo) ('\ n ',1) bar,len (bar) ('\ \ n ',2) foo==barfalse' \ n '是转义字符,这意味着ASCII中的换行符r' \ n '是原始字符串,原始字符串不转义特殊字符。它是您看到的字面意思,是由两个字符组成的字符串:“\”和“n”。
定义原始字符串可以以小写R或大写R开头,例如,允许使用r'\b '或R'\b '。在Python中,正则表达式通常以原始字符串的形式定义。为什么呢?
例如,对于字符' \b ',在ASCII中有特殊含义,表示退格键,而在正则表达式中,它是特殊的元字符,用于匹配单词的边界。为了让常规编译器正确表达其含义,它需要使用原始字符串。当然,它也可以使用反斜杠“\”来转义传统定义的字符串
Foo='\\b' bar=r'\b' foo==barTrue常规基本介绍
正则表达式由普通文本字符和特殊字符(元字符)组成。元字符在正则表达式中有特殊的含义,这使得正则表达式更具表现力。例如,在正则表达式r'a.d '中,字符“a”和“d”是普通字符。是元字符。可以指代任何字符,并且可以匹配“a1d”、“a2d”和“acd”。其匹配过程如下:
Python内置模块re是专门用于处理正则表达式的模块。
Rex=r'a.d' #正则表达式文本original _ str='和' #原始文本模式=re.compile(rex) #正则表达式对象m=pattern . match(origin _ str)# Matching对象m _ sre . sre _ match objectat0x 101 c 85 b 28 #相当于re。match (r' a.d ','和')_ sre . sre _ match objectat0x 10 a15 DC c8。如果原始文本字符串与正则表达式匹配,它将返回一个match对象。如果没有匹配,匹配方法将返回None。如果m是无,
接下来,我们需要学习更多元字符。
基本元字符。匹配除换行符以外的任何字符,例如,‘A . c’可以完全匹配‘ABC’或‘ABC’\:转义字符在‘abcef’中,这样特殊字符就有了本来的意义,例如1\.2可以匹配方括号中的任何字符,例如它还支持范围运算,例如:A到Z可以表示为‘A-Z’,0到9可以表示为‘0-9’。请注意,“[]”中的特殊字符不再具有特殊含义,即它们的字面含义,例如:[。*]是匹配项。或者* [.】,并且字符集是反转的,这意味着只要不是括号。
re.match(r'a.c ',' abc ')。group()'abc' re.match(r'a.c ',' abcef ')。group()'abc' re.match(r'1\.2 ',' 1.2 ')。group()'1.2' re.match(r'a[0-9]b ',' a2b ')。group()'a2b' re.match(r'a[0-9]b ',' a5b11 ')。group()'a5b' re.match(r'a[。*?]b ',' a.b ')。re.match(r'abc[^\w]',abc!123').group()'abc!Group方法返回原始字符串(abcf)中与正则表达式匹配的子字符串(abc)部分。事先,只有匹配方法匹配成功,匹配对象才会返回,然后组方法才可用。
预设元字符
\w匹配任何单词字符,包括数字和下划线,相当于[A-Za-z0-9_]。例如,a\wc可以匹配abc,acc\W可以匹配任何非单词字符。与\w操作相反,它相当于[a-za-z0-9 _],例如:a\Wc C\s匹配任何空白字符,空格和回车都是空白字符。例如,\sc可以与\nc匹配,其中\n表示回车\S匹配任何非空白字符\d匹配任何数字,相当于[0-9]。例如,a\dc可以匹配A2C的a1c.\.
边界匹配
与边界匹配相关的符号专门用于修改字符。
匹配字符的开头在字符串的前面,例如:abc表示匹配A开头后跟bc的字符串,可以匹配字符串结尾的abc$匹配字符的结尾,例如:hello $ re.match (r' ABC ',' Abc ')。组()‘ABC’re . match(r’ABC)
前面的元字符都匹配一个字符。如果希望匹配的字符重复出现,例如长度为18位的匹配ID号,则需要使用重复匹配的元字符
*重复匹配零次或多次?重复匹配零次或一次或多次{n}重复匹配n次{n,}重复匹配至少n次{n,m}重复匹配n到m次
#只需匹配身份证号码,前17位是数字,最后一位可以是数字或字母x re。匹配(r' \ d {17} [\ dx]',' 42350119900101153x ')。Group ()' 42350119900101153x' #匹配5到115。
匹配固定电话号码在不同地区有不同的规则。一些本地区号有3位数字,而另一些有4位数字和7位数字。区号和号码用-。如果我们满足了这个需求呢?此时,您需要使用逻辑分支条件字符|,它将表达式分为左右两部分。先试着匹配左边的部分。如果匹配成功,将不再匹配后一部分。这是一种逻辑“或”关系
# abc|cde可以匹配abc或cde,但要匹配ABC re。匹配(r' aa (ABC | CDE)'、' aabcccde ')。group()“aaabc”0 \ d { 2 }-\ d { 8 } | 0 \ d { 3 }-\ d { 4 }它也可以匹配7位数re。匹配(r' 0 \ d {2}-\ d {8} | 0 \ d {3}-\ d {7} ',' 0755-4348767 ')。group ()' 0755-4348767 '
上述匹配规则都是针对单个字符的。如果要重复匹配多个字符怎么办?答案是使用子表达式(也称为分组),分组用括号“()”表示。例如,(abc){2}表示匹配abc两次。匹配IP地址时,可以使用(\ d {1,3} \。){例如:192.168.0.1。
关于分组,可以使用group方法提取匹配的字符串分组。默认情况下,它会将整个表达式的匹配结果作为第0个分组,即group()或group(0)不带参数,括号中的第一组组由group(1)获得,依此类推
M=re。match (r' (\ d) (\ w '),' 123 AAC ')# group 0,匹配整个正则表达式m . group()' 123 AAC ' #等价的m . group(0)' 123 AAC ' # group 1,匹配第一对括号m.group (1)此外,还可以通过指定名称获得分组。
#第一个组的名称是number#第二个组的名称是char m=re.match(r '(?Pnumber\d()?Pchar \ w)'、' 123 AAC ')m . group(' number ')' 123 ' #等价m.group(1)'123 '贪婪和非贪婪
默认情况下,正则表达式重复匹配时,在整个表达式可以匹配的前提下,匹配尽可能多的字符。我们称之为贪婪模式,是一种贪得无厌的模式。比如说r'a。“b”表示匹配a的开头和b的结尾,中间可以是任意数量字符的字符串。如果它用于匹配aabcb,它将匹配整个字符串。
Re。匹配(r' a. * b ',' aabcb ')。group()‘aabcb’有时候,我们想要的匹配越少越好。我们做什么呢只需在量词“?”后面加一个问号,在保证匹配的情况下,尽量少匹配。例如,我们只想匹配aaab,所以我们只需要将正则表达式修改为r'a。*?' b '
重新匹配(r'a。*?' b ',' aabcb ')。group()“aaab”在crawler应用程序中经常使用。比如在微信官方账号的“Python Zen”中,我写了一个爬取网站并转换成PDF文件的场景。当img标签元素是网页上的相对路径时,我们需要用绝对路径替换它
html=' img src=' http :/images/category . png ' img src=' http :/images/js _ framework . png ' ' #两个在非贪婪模式下匹配的img标记#您可以更改为贪婪模式,看看有多少rex=r' img可以匹配。src='http:(。*?)' ' re.findall(rex,html)['/images/category.png ','/images/js _ framework . png ']def fun(match):img_tag=match.group().src=match.group(1).full_src='http://foofish.net' src.new _ img _ tag=img _ tag . replace(src,full_src).返回新的img标签.re.sub(rex,fun,Html)img src=' http:http://foofish.net/images/category.png' img src=' http:http://foofish.net/images/js _ framework . png ' sub函数可以接受一个函数作为替换目标对象,并用该函数的返回值替换正则表达式的匹配部分。在这里,我定义了整个img标签。src='http:(。*?)'',group()返回的值是img src=' http :/images/category.png ',而group(1)的返回值是/images/category . png,最后我用replace方法将相对路径替换为绝对路径。
至此,您应该对正则表达式有了初步的了解,现在我认为您应该能够解决文章开头提出的问题。
正则表达式的基本介绍到此结束。虽然代码示例中使用了re模块中的许多方法,但我还没有正式介绍该模块。考虑到文章的篇幅,我将把这一部分放在下一部分,介绍re的常用方法。
以上是边肖介绍的Python正则表达式完整指南,希望对大家有所帮助。如果你有任何问题,请给我留言,边肖会及时回复你。非常感谢您对我们网站的支持!
版权声明:Python正则表达式完整指南是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。