一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

python 正则表达式学习笔记

时间:2016-08-14 编辑:简简单单 来源:一聚教程网


正则表达式(regular expression)是一种用于匹配文本形式的强大逻辑表达式,在 Python 中的 re 模组提供了正则表达式的支持。正则表达式由一些普通字符和一些元字符(metacharacters)组成。普通字符包括大小写的字母和数字,而元字符则具有特殊的含义。

当正则表达式为一个普通的字符串时,一个正则表达式的匹配行为就是一个普通的字符串查找过程。例如,正则表达式"testing"中没有包含任何元字符,它可以匹配"testing"和"testing123"等字符串,但因为大小写敏感,它不能匹配"Testing"。其他一些元字符则不会被作为普通字符来处理,它们包括 . ^ $ * + ? { [ ] \ | ( ) 。

. 会匹配除了换行以外的任何字符; \w 等价于 [a-zA-Z0-9_] 会匹配单一字母、数字或下划线字符,而 \W 则会匹配任何非字母、数字和下划线的单一字符; \b 会匹配“单一字母、数字或下划线字符”和“任何非字母、数字和下划线的单一字符”之间的边界。 \s 等价于 [ \n\r\t\f] ,会匹配一个空白字符(包括空格、换行、返回、制表符、表格), \S 则匹配所有非空白字符; \t \n \r 依次用于匹配制表符、换行符、返回符; \d 等价于 [0-9] 用于匹配十进制表示的的数字。

^ 作为开始标记, $ 作为结束标记,分别用于标记一个字符串的开始和结束的位置。 \ 用于一些字符的转义,比如 \. 表示对于一个真实点字符的匹配, \\ 表示对于一个真实反斜杠字符的匹配等。如果你对不是很确定一些字符是否需要进行转义才能匹配,你大可都加上斜杠,比如对于 @ 你写成 \@ 是一定没有问题的。

import re

str = 'A cute word:cat!!'

match=re.search(r'word:\w\w\w',str)

if match:

print 'found',match.groups()

这里将用word:\w\w\w',str这个正则对str进行进行匹配查找,正则表达式前的r标记了这个表达式不用做转义处理,也就是说\n这种东西再被r标记了以后就不会当作换行处理,match变量将指向匹配查找的结果。

结果输出为 cat

import re
print re.search(r'..g','piiig').group()
print re.search(r'\d\d\d','p123g').group()
print re.search(r'\w\w\w','@@abcd!').group()

输出结果为:iig   123  abc
注:'..g' 查找g前的两个字母
    '\d\d\d' 查找字符串中的三个数字
    '\w\w\w'查找字符串中的三个单词字符  (若为'\w\w\w\w' 则输出abcd)
正则表达式中我们可以用+和*来实现重复多次的形式表达,*表示0或更多次的重复,+表示1或更多次的重复

import re
print re.search(r'pi+','piiig').group()
print re.search(r'pi*','pg').group()
输出:piii  p

 


 方括号的作用? 将一系列的正则字符以或的形式连接起来
import re
print re.search(r'[abc]+','xxxacbbcbbadddedede').group()
print re.search(r'[a-d]+','xxxacbbcbbadddedede').group()
输出为:acbbcbba  acbbcbbaddd
# 前者匹配了连续的由abc组成的字符串
# 后者匹配了从a到d的所有字母组成的俩许字符串
import re

str = 'purple alice-b@jisuanke.com monkey dishwasher'

match=re.search('([\w.-]+)@([\w.-]+)',str)

if match:

print match.group()

print match.group(1)

print match.group(2)

输出:alice-b@jisuanke.com

alice-b

jisuanke.com

注:在group()函数中加参数与不加参数的区别

正则表达式用简单的一些字符的组合包含了太丰富的语义,但是它们实在太过密集了,为了把你的正则表达式写对,你可能要花上太多太多的时间。在这里,我们提供一些简单的建议帮助你更高效的对正则表达式进行调试。

你可以设计一系列放在列表里的字符串用于调试,其中一部分是可以产生符合正则表达式的结果的,另一部分是产生不符合正则表达式的结果的。请注意,在设计这些字符串时,尽可能让他们的特征表现的更为不同一些,便于覆盖到我们可能出现的各种正则表达式没有写对的错误。例如,对于一个存在 + 的正则表达式,我们可以考虑选用一个符合 * 但是不符合 + 的字符串

然后你可以写一个循环,依次验证每个列表内的字符串是否符合指定的某个正则表达式并且和你设定的存在另一个列表内的预期结果进行比对,如果出现了不一致的情况,则你应该考虑看看你的正则表达式是不是还需要修改,如果结果基本一致,那么我们可以考虑进一步修改我们用于调试的字符串或添加新的字符串。

除了之前用到的search方法,在结合圆括号后,我们还可以使用另一个名 为findall的方法 来匹配查找出所有的被查找字符串符合正则的结果,并得到一个结果元组为元素的列表

import re
str = 'purple alice@jisuanke.com, blah monkey bob@abc.com blah dishwasher'
tuples=re.findall(r'([\w\.-]+)@([\w\.-]+)',str)
print tuples

输出:[('alice', 'jisuanke.com'), ('bob', 'abc.com')]


结合文件操作和 findall 的使用选出下面这段代码正确的输出结果

test.txt 的文本内容如下

 

 

在用于正则表达式的 re 模组中的函数有一些可选参数,我们可以对 search() 函数或者 findall() 函数传入额外的参数来进行使用,如  re.search(pat, str, re.IGNORECASE) 中的  re.IGNORECASE 就是使用了 re 中的一个标记作为额外的参数。

在 re 模组中,提供了很多不同的可选参数,其中上面提到的 IGNORECASE 表示了让匹配时忽略大小写的区别;而另外一个可选参数 DOTALL 如果被添加,则会允许正则中的 . 去跨行匹配,加了这个参数以后 .* 这样的匹配方式,将可以跨行进行匹配,而不只是在行内进行。另外,还有一个可选参数是 MULTILINE ,使用它以后,对于一个多行文本组成的字符串, ^ 和 $ 将可以用于匹配每一行的开始和结束,而如果没有用它时 ^ 和 $ 只会匹配整个字符串的开始和结束。

除了可选参数之外,我们还需要理解一下正则匹配的“贪心情况”。假设我们有一段文字 foo and so on 而你希望匹配 (<.*>) 提取的所有 HTML 标签,你觉得结果会是怎么样呢?我们可以得到期望的 这样的结果吗?

事实上的结果可能会有点出乎你的意料,因为  .* 这样的匹配是“贪心”的,它会尽可能去得到较长的匹配结果,因此我们会得到的是一整个 foo and so on 作为匹配出的结果。如果我们希望获得期望中的结果,我们就需要这个匹配是非贪心的,在正则表达式中,我们对于 * 和 + 这种默认贪心的匹配可以加上 ? 使之变为不贪心的。

也就是说,如果我们将 (<.*>) 改成 (<.*?>) ,正则表达式会先匹配 ,然后匹配 ,接下来则分别是 。这样的匹配结果与我们的预期完全一致。相应的,对于一些用到了 + 的情况,我们可以将 + 变为 +? 来进行非贪心的匹配。

热门栏目