自动化快速上手--python(24)--正则表达式

        这里是清安,本章我们来学习一下正则表达式,这也是前面没有接触过的。

        正则表达式有强大并且标准化的方法来处理字符串查找、替换以及用复杂模式来解析文本。正则表达式的语法比我们的程序 代码更紧凑,格式更严格,比用组合调用字符串处理函数的方法更具有可读性。甚至你可以在正则表达式中嵌入注释信息,这样就可以使它有自文档化的功能。

        直接看一则例子:

import re

s = 'My NAME IS QINGAN'
print(re.sub('QINGAN$', 'QA', s))

        首先,我们所学习的正则基于re模块。我们定义一个字符串,给定变量名为s,使用re中的sub方法。了解一下此处“^ 匹配字符串开始. $ 匹配字符串结尾“。所以我们这里匹配以QINGAN结尾的字符串,并用QA定性替代。s则是上述中的变量。

        那么再看看下面的例子:

import re

s = 'My NAME IS QINGAN'
print(re.sub('AN$', 'QA.', s))
print(re.sub('\\bAN$', 'ANAN', s))
print(re.sub(r'\bAN$', 'ANAN', s))

A = 'My NAME IS QINGANAN , QINGAN 2022'
print(re.sub(r'\bQINGAN$', 'QA.', A))
print(re.sub(r'\bQINGAN\b', 'QA.', A))

        为了在正则表达式中表达这个独立的词,你可以使用‘\b’。它的意思是在右边必须有一个分隔符。但是需要被转义,所以我加了r进行转义。

My NAME IS QINGQA.
My NAME IS QINGAN
My NAME IS QINGAN
My NAME IS QINGANAN , QINGAN 2022
My NAME IS QINGANAN , QA. 2022

        上述的结果就是这样,为什么\b..$的输出的还是一样的内容,上面说了\b的作用跟$的作用,因此,没有对应的匹配内容,此处需要匹配以QINGAN为结尾的字符串,但是碍于\b的作用,所以此处匹配不到。

        简单的小实例:

import re

phonePattern = re.compile(r'^(\d{3})‐(\d{3})‐(\d{4})$')
i = phonePattern.search('111‐555‐2222').groups()
print(i)

        此处用了re模块中的compile跟search方法。首先是匹配字符串开始位置,然后是(\d{3})\d{3}表示什么意思?\d 表示任意的数字(0 9),{3}表示一定要匹配 3 个数字。并且把他们记做一个组。然后匹配一个连字符,接着匹配另外的 3 个数字,他们也同样作为一个组。然后又是一个连字符,后面还要准确匹配 4 个数字,他们也作为一位分组。最后匹配字符串结尾。

        为了使用正则表达式匹配到的这些分组,需要对 search()数的返回值调用 groups()方法。它会返回一个这个正则表达式 中定义的所有分组结果组成的元组。结果展示:

('111', '555', '2222')

        那么如果我后续还有很多的字符串或者我的字符串中间没有”-“怎么办呢。

phonePattern1 = re.compile(r'^(\d{3})\D+(\d{3})\D+(\d{4})\D+(\d+)$')
o = phonePattern1.search('111 222 3334 444').groups()
p = phonePattern1.search('111‐222‐3333‐4444').groups()
print(o, p)

        匹配了字符串开始,然后是 3 个数字的分组,接着是\D+\D 匹配除了数字以外的任意字符,+的意思是一个或多个。因此\D+匹配一个或一个以上的非数字字符。这就是你用来替换连字符的东西,它用来匹配不同的分隔符。用\D+替换,意味着你可以匹配分隔符为空格的情况。

('111', '222', '3334', '444') ('111', '222', '3333', '4444')

        那么如果说我是连着的情况呢亦或者字符串中有一个英文字符。

import re

phonePattern = re.compile(r'^(\d{3})\D*(\d{3})\D*(\d{4})\D*(\d*)$')
i = phonePattern.search('1112223331234').groups()
o = phonePattern.search('111.222.3333 x1234').groups()
y = phonePattern.search('111‐222‐3333').groups()
print(i, o, y)

        这里和上面唯一不同的地方是,把所有的+换成了*。号码之 间的分隔符不再用\D+来匹配,而是使用\D*。还记得+表示一个或更多。现在可以解析号码之间没有分隔符的情况了。

        看变量o多了一个x但是,我们正则写的是\d*所以,此处的x是匹配不到的。

        那么我们再完善一下这个正则,让它过滤掉其他的情况,例如多了括号等情况:

import re

phonePattern = re.compile(r'^\D*(\d{3})\D*(\d{3})\D*(\d{4})\D*(\d*)$')
i = phonePattern.search('(111)2224444 com.1234').groups()
print(i)

        ^:匹配字符串的开头。现在除了在第一个分组之前要用\d*匹配 0 个或更多非数字字符外,这和前面的例子是相同的。注意你不会对这些非数字字符分组,因为他们不在圆括号内,也就是说不是一个组。即使区位码之前有圆括号,你也可以成功的解析电话号码了。(右边的圆括号已经处理,它被\D*匹配成一个非数字字符)。如果发现有这些字符,这里只是跳过他们,然后开始对后面的区域码匹配、分组。  

        最后还有一个例子需要注意一下。'work 1‐(111) 222.3333 #1234'。这种情况下,我们上述的正则是匹配不到的,那么怎样才能匹配到呢。

import re

# phonePattern = re.compile(r'^\D*(\d{3})\D*(\d{3})\D*(\d{4})\D*(\d*)$')
phonePattern = re.compile(r'(\d{3})\D*(\d{3})\D*(\d{4})\D*(\d*)$')
i = phonePattern.search('work 1‐(111) 222.3333 #1234').groups()
print(i)

        注意正则表达式没有^。不会再匹配字符串开始位置了。正则表达式不会匹配整个字符串,而是试图找到一个字符串开始匹配的位置,然后从这个位置开始匹配。 

        以下是本章所用到的小总结。

• ^ 匹配字符串开始位置。  
• $ 匹配字符串结束位置。  
• \b 匹配一个单词边界。  
• \d 匹配一个数字。  
• \D 匹配一个任意的非数字字符。   
• x* 匹配 0 个或更多的 x。  
• x+ 匹配 1 个或者更多 x。  
• x{n,m} 匹配 n 到 m 个 x,至少 n 个,不能超过 m 个。    
• (x) 这是一个组,它会记忆它匹配到的字符串。你可以用
re.search 返回的匹配对象的 groups()函数来获取到匹配的值。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清安无别事

慢慢的积累一杯奶茶吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值