盒子
盒子

Python正则表达式(一)

在实际生活中经常面对的问题是要检索出具有某种形式的字符串而不是某个字符串,这种检索只考虑字符串的形式而不考虑其字面意义,Python中的正则表达式可以帮我们很好的完成字符串的检索和匹配等操作。

正则表达式

正则表达式是一种描述字符串集合的语言,其基本组成是普通字符、特殊组合结构以及表示组合的括号,一个正则表达式描述了字符集上的一组特定的字符串。

简单示例

假设α和β都是正则表达式,则:

  • 正则表达式里的普通字符至于该字符本身匹配
  • 顺序组合αβ:如果α能匹配字符串s,β能匹配字符串t,则αβ能匹配字符串拼接s+t
  • 选择组合α|β:如果α能匹配s,β能匹配字符串t,则α|β能匹配字符串s或者字符串t
  • 星号α*:如果α能匹配字符串s,则α*能匹配能匹配空串、s、s+s、s+s+s等等,即α* 能匹配0个或任意多个s字符串的拼接。

正则表达式还可以用括号表示表达式的组合,例如:

  • 正则表达式abc只与字符串abc匹配
  • a(b*)(c*):与在一个a开头的字符串且后面跟着0至任意多个b,之后再跟0至任意多个c的字符串匹配,相当于a[任意多个b][任意多个c]的字符串。
  • a(b|c)*:与所有一个a开头的字符串且后面跟有任意多个b和c的串进行匹配,相当于a[空串或者b或c的任意组合]

正则表达式的常见元素

  • 任一字符仅与其自身匹配
  • 圆点符号.可以匹配任意字符
  • 符号^匹配目标串的开头,不匹配任何具体字符
  • 符号$匹配目标串的结尾,不匹配任何具体字符
  • 符号*表示其前面的字符可以重复出现0次或者任意多次

注意:*和$符号至多在匹配模式的开始和结束出现一次

Python正则表达式

大多数编程语言都提供了正则表达式的功能,Python通过标准库re提供,利用正则表达式可以实现许多复杂的字符串操作,想要使用Python的一些正则表达式功能和方法需要首先导入re包:

1
import re

下面我们以一个实际问题来演示Python中如何使用正则表达式:

问题:求一个Python程序里面出现的所有整数之和(Python语言中把一元的正负号看作运算符,不是整数的一部分,注意去掉注释行)

Python实现代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# !/usr/bin/env python
# coding: UTF-8

import re

def sumCount(fname):
re_pattern = r'\b(0|[1-9]\d*)\b'
fobj = open(fname, 'rb')
if fobj == None:
return None
f_list = map(int, re.findall(re_pattern, fobj.read()))
result = 0
for i in f_list:
result += i
return result

if __name__ == '__main__':
fname = raw_input("Enter file name: ")
print "Result:", sumCount(fname)

上面代码中,re_pattern = r'\b(0|[1-9]\d*)\b'是匹配模式,map()函数将查找到的所有整数转换为int类型并声称结果列表,在之后的for循环中迭代相加。

Python正则表达式的构造

字符组

描述一组字符,某些正则表达式可以与一组字符中的任意一个字符匹配,这种描述方式称为字符组描述。

字符组描述符[…]

与方括号中列出的字符中的任意一个匹配,例如[abc]与a或b或c之中的一个匹配。此外还可以进行如下模式的匹配:

  • 字符区间形式:例如[a-z]匹配字符a到字符z之间的任意一个字符,[A-Za-z]匹配任意的一个大小写英文字母,[A-Za-z0-9]匹配任意的一个大小写字母或数字
  • 取反形式[^…]:表示对^之后的字符求补,例如[^0-9]匹配非数字字符,[^\t\v\n\f\r]匹配所有非空字符(除去空格、制表符、换行符)

注意:如果字符组里包含^-]字符,需要写成\^\-\]的形式

圆点字符(.)

圆点是通配符,它能匹配任何字符。例如a..b匹配所有啊、以a开头以b结尾的长度为4的字符串。
为了方便,re采用转义串的形式定义了一些常用的字符组:

  • \d:匹配十进制数字,等价于[0-9]
  • \D:与所有非十进制的字符匹配,等价于[^0-9]
  • \s:与所有空白字符串匹配,等价于[ \t\v\n\f\r]注意空格
  • \S:与所有非空字符串匹配,等价于[^ \t\v\n\f\r]
  • \w :与所有字母数字字符匹配,等价于[0-9a-zA-Z]
  • \W:与所有非字母数字匹配,等价于[^0-9a-zA-Z]

例如:a\d*\W匹配以字符a开头,之后跟有0或多个数字,之后以一个非字母且非数字的字符结尾的字符串。