正则表达式与python中re模块
一个网站,正则表达式入门的,很好
http://www.jb51.net/tools/zhengze.html
下面这个包含对python中re的介绍,也是很不错的
http://www.w3cschool.cc/python/python-reg-expressions.html
正则表达式的入门,上个链接就写的很好,就不再叙述关于正则表达式的知识。
下面介绍一下python 中re模块,也就是正则表达式匹配相关的用法。
版本python 3.4.3
re.match
1
2
3
4
5
6
|
>>> import re >>> text = "JGood is a handsome boy, he is cool, clever, and so on..." >>> m = re.match(r "(\w+)\s" , text) >>> if m: print (m.group( 0 )) JGood |
re.match的函数原型为:re.match(pattern, string, flags)
第一个参数是正则表达式,这里为"(\w+)\s",如果匹配成功,则返回一个Match,否则返回一个None;
第二个参数表示要匹配的字符串;
第三个参数是标致位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
匹配对象方法 | 描述 |
group(num=0) |
匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。 |
groups() |
返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。 |
re.search
re.search函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回,如果字符串没有匹配,则返回None。
1
2
3
4
5
6
7
|
>>> o = re.search(r 'handsome' ,text) >>> >>> if o: print (o.group( 0 )) else : print ( "None" ) Handsome |
re.search的函数原型为: re.search(pattern, string, flags)
每个参数的含意与re.match一样
re.match与re.search的区别:re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
re.sub
re.sub用于替换字符串中的匹配项。下面一个例子将字符串中的空格 ' ' 替换成 '-' :
1
2
|
>>> print (re.sub(r '\s+' , '-' , text)) JGood - is - a - handsome - boy, - he - is - cool, - clever, - and - so - on... |
re.sub的函数原型为:re.sub(pattern, repl, string, count)
其中第二个函数是替换后的字符串;本例中为'-'
第四个参数指替换个数。默认为0,表示每个匹配项都替换。
re.sub还允许使用函数对匹配项的替换进行复杂的处理。如:re.sub(r'\s', lambda m: '[' + m.group(0) + ']', text, 0);将字符串中的空格' '替换为'[ ]'。
re.split
可以使用re.split来分割字符串,如:re.split(r'\s+', text);将字符串按空格分割成一个单词列表。
1
2
|
>>> re.split(r '\s+' , text) [ 'JGood' , 'is' , 'a' , 'handsome' , 'boy,' , 'he' , 'is' , 'cool,' , 'clever,' , 'and' , 'so' , 'on...' ] |
re.findall
re.findall可以获取字符串中所有匹配的字符串。如:re.findall(r'\w*oo\w*', text);获取字符串中,包含'oo'的所有单词。
1
2
|
>>> re.findall(r '\w+oo\w+' ,text) [ 'JGood' , 'cool' ] |
re.compile
可以把正则表达式编译成一个正则表达式对象。可以把那些经常使用的正则表达式编译成正则表达式对象,这样可以提高一定的效率。下面是一个正则表达式对象的一个例子:
1
2
3
|
>>> regex = re. compile (r '\w+oo\w+' ) >>> print (regex.findall(text)) [ 'JGood' , 'cool' ] |
下面这个的作用是#将字符串中含有'oo'的单词用[]括起来。但是从语法上来讲,我并没有看明白。
知道可以这么用就好了
1
2
|
>>> print (regex.sub( lambda m: '[' + m.group( 0 ) + ']' ,text)) [JGood] is a handsome boy, he is [cool], clever, and so on... |
下面是关于lambda的一个简单回顾:
1
2
3
|
def f(x): return x * * 2 print f( 4 ) |
Python中使用lambda的话,写成这样
1
2
|
g = lambda x : x * * 2 print g( 4 ) |
1. 使用Python写一些执行脚本时,使用lambda可以省去定义函数的过程,让代码更加精简。
2. 对于一些抽象的,不会别的地方再复用的函数,有时候给函数起个名字也是个难题,使用lambda不需要考虑命名的问题。
3. 使用lambda在某些时候让代码更容易理解。
在对象遍历处理方面,其实Python的for..in..if语法已经很强大,并且在易读上胜过了lambda。比如上面map的例子,可以写成:
1
|
print [x * 2 + 10 for x in foo] |
非常的简洁,易懂。filter的例子可以写成:
1
|
print [x for x in foo if x % 3 = = 0 ] |
同样也是比lambda的方式更容易理解。
所以,什么时候使用lambda,什么时候不用,需要具体情况具体分析,只要表达的意图清晰就好。一般情况下,如果for..in..if能做的,我都不会选择lambda。
lambda broken?
在数学教学中,经常会使用到lambda,比如有一位老兄就遇到这样一个问题。他想创建一个函数数组fs=[f0,...,f9] where fi(n)=i+n. 于是乎,就定义了这么一个lambda函数:
1
|
fs = [( lambda n: i + n) for i in range ( 10 )] |
但是,奇怪的是,
1
2
3
4
5
6
|
>>> fs[ 3 ]( 4 ) 13 >>> fs[ 4 ]( 4 ) 13 >>> fs[ 5 ]( 4 ) 13 |
结果并没有达到这位老兄的预期,预期的结果应该是:
1
2
3
4
5
6
|
>>> fs[ 3 ]( 4 ) 7 >>> fs[ 4 ]( 4 ) 8 >>> fs[ 5 ]( 4 ) 9 |
面没有达到预期的原因是lambda中的i使用的是匿名函数外的全局变量。修改一下,就可以了:
1
2
3
4
5
6
7
|
fs = [( lambda n, i = i : i + n) for i in range ( 10 )] >>> fs[ 3 ]( 4 ) 7 >>> fs[ 4 ]( 4 ) 8 >>> fs[ 5 ]( 4 ) 9
|