python--进阶正则--2022-18

105 阅读1分钟

「这是我参与2022首次更文挑战的第18天,活动详情查看:2022首次更文挑战

​这里是清安,上一章我们简单的了解了一下正则,本章来深入学习学习正则。

 简单的小实例:

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)

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

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