正则表达式学习与python中的应用
目录:
一、正则表达式的特殊符号
二、几种重要的正则表达式
三、python的re模块应用
四、参考文献
一、正则表达式的特殊符号
特殊符号可以说是正则表达式的关键,掌握并且可以灵活运用重要的python符号,基本就搞定了正则表达式,不过我不敢说自己已经到了炉火纯青的地步。
.(点号),该符号可以匹配任何的字符,当然要换行符除外。在python中,如果存在re.DOTALL,那么即使是换行符,也同样可以匹配,这个DOTALL就是一个标记flag.
eg:re.compile(r'\b\w.’,re.DOTALL)
说明:
1.这个点号和字符串的点不要混淆,如果不用该符号,而用自己编写的正则表达式,想匹配点号,就一定要加个转义符\.
2.正则表达式使用反斜杠" \ "来代表特殊形式或用作转义字符。正则表达式字符和ASCII字符之间有冲突,比如\b表示退格键,但是在正则表达式中表示以某个字符或字符串为边界。要想不发生冲突就要用转义字符,但如果每个正则表达式都用上转义字符,会变得很麻烦,所以原始字符串就应用而生了,它主要是解决该类问题,只需在正则表达式外加上r即可。
^ 表示匹配字符串的开头。如果存在多行字符串,那么可以加上re.M,就可以匹配多行的开头了。^ds
$该符号与上一个正好相反,它匹配的是结尾。
* 表示它左边的正则表达式出现0次或者0次以上。
+表示它左边的正则表达式出现至少一次以上。
?表示它左边的正则表达式出现0次或1次。
管道符号“|”,竖杠相当于 或者,可以不止匹配一个字符串,可以匹配被管道符号分割的多个字符串。
[]匹配方括号内任意一个字符串 b[aeiu]t 可以匹配 bat, bet, bit, but.[0-9] 匹配0-9的任何一个数。
花括号{},花括号里面可以是单个值,也可以是一对值,若是单个值n,就表示匹配n次,若是一对值,就表示匹配次数为一个范围。{m} {m,n}
\A 只在字符串的开头匹配
\b 表示边界
\bthe匹配以the开始的字符串
the\b匹配以the结尾的字符串
\bthe\b 匹配单词the
\d匹配任何一个数字,相当于[0-9]
\s表示空白字符,就是空格。
\w代表整个字符数字的字符集,相当于A-Z a-z 0-9
\Z 只匹配字符串的结尾。
[^x]匹配除了字母x的字符,[^xty]匹配除了字母xty的字符。
注意:所有的大写都表示相应的不匹配。
()组建组
以上介绍的基本都是单个字符的重复,如果是多个字符就用元祖
比如:(ab)+,匹配一个以上的ab.
它的另外一个作用是记录,可以用re中的group,groups查看。
分析一种形式,主要为了说明转义字符的用处:
正则表达式:\(?0\d{2,3}[) -]?\d{8}
它一般是用来匹配固定电话的,前面是区号,后面是号码.
我们对它进行详细分析:
1.电话前面的区号一般是除了第一位0,可能有两位010,也可能有3位,0451。所以括号\d{2,3};后面的号码一般都是6位的。\d{8}
2.现在看前面。\(?,前面的\是转义符,因为电话号码可以有两种表示形式((0451)57561101,或者0451-57561101)。因为括号(也是表达式的元字符,所以要匹配它,要加上转义符后面的问号表示出现0次或者1次。
3.[)-],表示匹配),或者连接符-。
二、几种重要的正则表达式
(?......),问号?后面跟着一串字符或者其他神马的,紧跟着问号’?‘后面的第一个字符或者符号决定了该结构struct的含义以及语法。下面就几种就是不同的该形式的扩展。
1、(?<=xyz) 在一个字符串中,匹配到xyz,然后匹配随后的字符
eg: r’(?<=xyz)abc,’adxyzabc’,输出就是abc
2、(?=......) 与上一个正好相反,匹配之前的字符。
3、(?P<name>.....),匹配相应字符,并将文本保存在名为name的组里。
4、(?p=name) 对被命名过的组回溯引用,它可以匹配任何之前的某个指定的group匹配的文本 ,但要注意,如果查看要加引号。m.group('name')
(?P<quote>['"]).*?(?P=quote)(from python.org)
5、(?:.......) 表示非记录分组,这个分组不会被记录下来,即只匹配,并不捕获匹配的文本,也不给此分组分配组号。(我在验证时,groups返回的一个空组)
6、(?#......)主要是用来提供注释,对正则表达式不产生任何的影响。
7、(?!xyz) 匹配该位置后面跟的不是xyz的字符
8、(?<!xyz)匹配该位置前面不是xyz的字符
三、python的re模块应用
通过调用dir函数,查询re属性,如下是re模块含有的所有属性
['DEBUG', 'DOTALL', 'I', 'IGNORECASE', 'L', 'LOCALE', 'M', 'MULTILINE', 'S', 'Scanner', 'T', 'TEMPLATE', 'U', 'UNICODE', 'VERBOSE', 'X', '_MAXCACHE', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__version__', '_alphanum', '_cache', '_cache_repl', '_compile', '_compile_repl', '_expand', '_pattern_type', '_pickle', '_subx', 'compile', 'copy_reg', 'error', 'escape', 'findall', 'finditer', 'match', 'purge', 'search', 'split', 'sre_compile', 'sre_parse', 'sub', 'subn', 'sys', 'template']
compile
预编译正则表达式规则,以便后续使用该正则表达式方便,会返回一个正则对象,regex.
eg:prog = re.compile(pattern) pattern 是你自己定义的正则表达式
search ,match,findall
之所以把他们一起讨论,是因为有相同点,也有不同点。
相同点都是搜索字符根据特定的正则表达式进行匹配;
不同点:
match只是匹配字符串的开头,如果不匹配,就退出,返回一个None。
search可以匹配字符串的任意位置,如果整个字符串都不匹配,返回一个None
findall和search差不多,只不过时它始终返回一个列表,即使不匹配,也要返回一个空列表[],而search和match返回的是元祖。
result = prog.match(string)
print result.group() group是子元祖,如果显示所有的,就用groups。
result = prog.search(string)
print result.group()
result = prog.findall(string)
print result
split(pattern,string, max=0) 根据正则表达式pattern 中的分隔符把字符string 分割 为一个列表,返回成功匹配的列表,最多分割max 次(默认是分割所有匹配的地方)。 re.split(':','fe:dw:efg')
sub(pattern, repl, string, max=0) 把字符串string 中所有匹配正则表达式pattern 的地方替换成字符串repl,如果max 的值没有给出,则对所有匹配的地方进行替换(另外,请参考subn(),它还会返回一个表示替换次数的数值)。
几种特殊标志flags:
- re.I(re.IGNORECASE): 忽略大小写(括号内是完整写法,下同)
- M(MULTILINE): 多行模式,改变'^'和'$'的行为(参见上图)
- S(DOTALL): 点任意匹配模式,改变'.'的行为
- L(LOCALE): 使预定字符类 \w \W \b \B \s \S 取决于当前区域设定
- U(UNICODE): 使预定字符类 \w \W \b \B \s \S \d \D 取决于unicode定义的字符属性
- X(VERBOSE): 详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释。以下两个正则表达式是等价的:
- DOTALL,前文中已经讲解。
eg:
a
=
re.
compile
(r
"""\d + # the integral part
\. # the decimal point
\d * # some fractional digits"""
, re.X)
b
=
re.
compile
(r
"\d+\.\d*"
)
下面的是我在cygwin中用vim编写的简单的re模块,已验证。
6 a='800-555-122'
7 b='555-123'
8 p=re.compile(r'(\d{3})?-?(\d{3})-?(\d*)')
9 print p.findall(a)
10
11
12 c=re.search(r'[bh][aiu]t','bit')
13 print c.group()
14 d=re.search(r'\w+,\s\w','Dywane, W')
15 print d.group()
16
17 url=['www.baidu.com','www.sina.cn','www.bjtu.edu.cn']
18 q=re.compile(r'(www.)\w*\.(com|cn|edu)\.?\w*')
19 for i in range(len(url)):
20 try:
21 print url[i]
22 r=q.search(url[i])
23 if r!=None:
24
25 print 'match success',r.group()
26 else:
27 pass
28 except:
29 print 'Error'
30
31 print "15-4,match all python's indicator"
32
33 print re.search(r'\d+','133234').group()
34 print re.search(r'\d+\.?\d*','2').group()
35
36 t=str(type(0))
37 print t
38 w=re.search(r"(?<=type\s\')\w+",t).group()
39 if w==None:
40 pass
41 else:
42 print w
43
44 print re.search(r'[0-9][0-2]?','2').group()
四、参考文献
【1】 python核心编程第二版
【2】www.python.org的module部分,re模块
【3】Learning python
【4】python从入门到精通
【5】 python 程序开发指南