python学习——正则表达式

时间:2022-11-11 16:02:15

python学习——正则表达式

  • 正则表达式是一种用来匹配字符串的强有力的武器。它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。
  • 在正则表达式中,如果直接给出字符,就是精确匹配。用  \d 可以匹配一个数字,  \w 可以匹配一个字母或数字。  .  可以匹配任意字符。
  • 要匹配变长的字符,在正则表达式中,用  *  表示任意个字符(包括0个),用  表示至少一个字符,用  表示 0 个或 1 个字符,用  {n}  表示 n 个字符,用  {n,m}  表示 n-m 个字符。
  •   \s  可以匹配一个空格(也包括Tab等空白符),所以  \s+  表示至少有一个空格,例如匹配 ' ','   ' 等;

进阶

  • 要做更精确地匹配,可以用[]表示范围,比如:
  •   [a-zA-Z\_][0-9a-zA-Z\_]*  可以匹配由字母或下划线开头,后接任意个由一个数字、字母或者下划线组成的字符串,也就是Python合法的变量;
  •   [a-zA-Z\_][0-9a-zA-Z\_]{0, 19}  更精确地限制了变量的长度是1-20个字符(前面1个字符+后面最多19个字符)。
  •   A|B  可以匹配A或B,所以(P|p)ython可以匹配'Python'或者'python'。
  •   ^  表示行的开头,  ^\d  表示必须以数字开头。
  •   $  表示行的结束,  \d$  表示必须以数字结束。

re模块

  • Python提供re模块,包含所有正则表达式的功能。由于Python的字符串本身也用\ 转义,所以要特别注意。因此我们强烈建议使用Python的r 前缀,就不用考虑转义的问题了。

'hello\\nworld' == r'hello\nworld' == (hello\nworld)

  • match() 方法判断是否匹配,如果匹配成功,返回一个Match 对象,否则返回None

切分字符串

  • 无论多少个空格都可以正常分割。其他字符同理。如果用户输入了一组标签,下次记得用正则表达式来把不规范的输入转化成正确的数组。

import re
print(re.split(r'[\s\,\;\-]+', '2017----;06,, 12'))


['2017', '06', '12']

分组

  • 除了简单地判断是否匹配之外,正则表达式还有提取子串的强大功能。用()表示的就是要提取的分组(Group)。比如:^(\d{3})-(\d{3,8})$ 分别定义了两个组,可以直接从匹配的字符串中提取出区号和本地号码。
  • 如果正则表达式中定义了组,就可以在  Match  对象上用  group()  方法提取出子串来。注意到  group(0)  永远是原始字符串,group(1)、group(2)……表示第1、2、……个子串。

>>> t = '19:05:30'
>>> m = re.match(r'^(0[0-9]|1[0-9]|2[0-3]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])$', t)
>>> m.groups()
('19', '05', '30')

贪婪匹配

  • 最后需要特别指出的是,正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符。

编译

  • 当我们在  Python  中使用正则表达式时,re 模块内部会干两件事情:(1) 编译正则表达式,如果正则表达式的字符串本身不合法,会报错;(2) 用编译后的正则表达式去匹配字符串。
  • 编译后生成 Regular Expression 对象,由于该对象自己包含了正则表达式,所以调用对应的方法时不用给出正则字符串。

# !usr/bin/env python3
# -*- coding: utf-8 -*-
# for regular expression in 2017-06-12


''' 请尝试写一个验证Email地址的正则表达式。
版本一:应该可以验证出类似的Email: someone@gmail.com bill.gates@microsoft.com
版本二:可以验证并提取出带名字的Email地址:<Tom Paris> tom@voyager.org'''


import re
re_email = re.compile(r'([a-zA-Z0-9]+\.?[a-zA-Z0-9]+)\@(\w+)\.([a-z]+\.?[a-z]+)$')
re_name_email = re.compile(r'(^\<[A-Z][a-z]+\s[A-Z][a-z]+\>)\s([A-Za-z0-9]+)\@([a-zA-Z0-9]+)\.([a-z]+)$')


str_list = ['someone-gmail.com', 'bill.gates@microsoft.com.cn', '123456@qq.com', '<Tom Paris> tom@voyager.org']


for i in range(len(str_list)):
if (None != re_email.match(str_list[i])):
print('>>:', i + 1, str_list[i], re_email.match(str_list[i]).groups())
else:
print('>>:', i + 1, str_list[i], 'not match !!!')


if (None != re_name_email.match(str_list[-1])):
print('>>: -1', str_list[-1], re_name_email.match(str_list[-1]).groups())
else:
print('>>: -1', str_list[-1], 'not match !!!')
结果:
Connected to pydev debugger (build 171.4424.42)
>>: 1 someone-gmail.com not match !!!
>>: 2 bill.gates@microsoft.com.cn ('bill.gates', 'microsoft', 'com.cn')
>>: 3 123456@qq.com ('123456', 'qq', 'com')
>>: 4 <Tom Paris> tom@voyager.org not match !!!
>>: -1 <Tom Paris> tom@voyager.org ('<Tom Paris>', 'tom', 'voyager', 'org')

Process finished with exit code 0

----------------------------------------------------------------------------------------------------------------------------
参考网站:http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000
----------------------------------------------------------------------------------------------------------------------------