Python笔记7(正则表达式)

11. 正则表达式

字符串 是编程时涉及到的最多的一种数据结构,对字符串进行操作的需求几乎无处不在。正则表达式是一种用来匹配字符串的强有力的武器。

正则表达式的设计思想:是用一种描述性的语言来给字符串定义一个法则,凡是符合规则的字符串,就认定它“匹配”了,否则该字符串就是不合法的。

判断一个字符串是否合法的Email的方法:

  • 创建一个匹配Email的正则表达式
  • 用该正则表达式去匹配用户的输入来判断是否合法

正则表达式中,直接给出字符就是精确匹配

表达式 说明 举例
0 匹配数字0,两个0则匹配两个数字0 0
\d 0-9的一个数字 1或2或3
\w 一个字母或数字 0或a或B
. 任意一个字符 c或0或!或#等等
* 匹配任意个字符(包括0个)
+ 至少一个字符
? 0个或1个字符
{n} n个字符,用{n,m}表示n-m个字符
\d{3} 匹配3个数字 010124
\s 匹配一个空格(包括Tab等空白符) ' '
\s+ 匹配至少有一个空格 例如匹配' '' '
\d{3,8} 匹配3-8个数字 1234567
  • demo.匹配010-12345-是特殊字符,在正则表达式中用'\'转义,所以应该是\d{3}\-\d{3,8}

1. 进阶

做更精确的匹配,可用[]表示范围:

  • [0-9a-zA-Z\_]:匹配一个数字、字母或下划线
  • [0-9a-zA-Z\_]+:匹配至少由一个数字、字母或下划线组成的字符串,比如'a100'''0_Z''Py3000'
  • [a-zA-Z\_][0-9a-zA-Z\_]*:可匹配由字母、数字或下划线开头,后接任意个由一个数字、字母或下划线组成的字符串,也就是Python合法的变量
  • [a-zA-Z\_][0-9a-zA-Z\_]{0,19}更精确的限制了变量的长度是1-20个字符(前面一个字符+后面最多19个字符)
表达式 说明 举例
| 逻辑关系“或” A|B匹配AB(P|p)ython可匹配'Python''python'
^ 行的开头 ^\d表示必须以数字开头
$ 行的结束 \d$表示必须以数字结束。py可匹配’hpy’‘pyt’,但加上^py$就只能匹配‘py’`

2. re模块

Python的re模块包含所有正则表达式的功能

Python的字符串本身也用\转义,所以需要注意,但字符串前加r就不用考虑转义的问题了:r'abc'

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

>>> import re
>>> re.match(r'\d{3}\-\d{3,8}$','010-12345')  # 成功示例
.Match object; span=(0, 9), match='010-12345'>
>>> re.match(r'\d{3}\-\d{3,8}$','010 12345')  # 失败示例
>>>

3. 切分字符串

用正则表达式切分字符串比用固定的字符更灵活。

语法:re.split(r'表达式',字符串)

  • 正常切分(无法识别连续的空格):
>>> 'a b  c'.split(' ')
['a', 'b', '', 'c']
  • 正则表达式 \s+匹配至少一个空格(可以识别连续空格):
>>> re.split(r'\s+','a b  c')
['a', 'b', 'c']
  • 正则表达式 分隔空格和,
>>> re.split(r'[\s\,]+','a,b, c  d')
['a', 'b', 'c', 'd']
  • 正则表达式 分隔空格、,;
>>> re.split(r'[\s\,\;]+','a,b; c  d')
['a', 'b', 'c', 'd']

如果用户输入一组标签,可用正则表达式把不规范的输入转化成正确的列表。

分组

正则表达式除判断是否匹配外还有提取子串的强大功能。用()表示要提取的分组(Group)。比如^(\d{3})-(\d{3,8})$分别定义了两个组,可直接从匹配的字符串中提取出区号和本地号码:

>>> m = re.match(r'^(\d{3})-(\d{3,8})$','010-12345')
>>> m
.Match object; span=(0, 9), match='010-12345'>
>>> m.group(0)
'010-12345'
>>> m.group(1)
'010'
>>> m.group(2)
'12345'
>>> m.group(3)
Traceback (most recent call last):
  File "", line 1, in 
IndexError: no such group

上边的例子中设置了两个组,在Match对象上用group()方法提取子串:

  • group(0)group()是原始字符串
  • group(1)是第1个子串,group(2)是第2个子串,超出范围报错
  • re.match().groups()会以元组形式返回组信息

贪婪匹配

正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符。

demo:匹配出数字后面的0

>>> re.match(r'^(\d+)(0*)$','102300').groups()
('102300', '')
  • 由于\d+采用贪婪匹配,直接把后面的0全部匹配了,结果0*只能匹配空字符串了。
  • 必须让\d+采用非贪婪匹配(也就是尽可能少匹配),才能把后面的0匹配出来,加个?就可以让\d+采用非贪婪匹配:
>>> re.match(r'^(\d+?)(0*)$','102300').groups()
('1023', '00')

编译

Python使用正则表达式时,re模块内部会干两件事:

  • 编译正则表达式,如果正则表达式的字符串本身不合法,会报错
  • 用编译后的正则表达式去匹配字符串

如果一个正则表达式要重复使用几千次,出于效率的考虑,可以预编译该正则表达式,接下来重复使用时就不需要编译这个步骤了,直接匹配:

>>> re_telephone.match('010-12345').groups()
('010', '12345')
>>> re_telephone.match('010-9527').groups()
('010', '9527')

编译后生成Regular Expression对象,该对象自己包含正则表达式,所以调用对应方法时不用给出正则表达式。

你可能感兴趣的:(Python笔记与练习题,python,正则表达式,字符串)