正则表达式
什么是正则表达式
正则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE),又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法,是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。----引自维基百科
相信大家肯定都遇到过这种情况,就是在windows系统中要快速的找到某个目录下的所有的doc格式的文档,在windows底下我们怎么做的呢?你会在windows的搜索框中输入.doc。在这里,‘’会被解释成任意的字符串,和通配符类似,正则表达式也是用来进行文本匹配的工具,它比通配符更能精确地描述你的需求。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。许多程序设计语言都支持利用正则表达式进行字符串操作。Python也不例外,下面我们来详细讲解在Python中的正则表达式是什么样的。
因为正则表达式通常用于字符匹配和检索,所以我认为简单的理解,要写一个正则表达式主要包括两方面,一个是做字符匹配,另一个是做次数匹配。
字符匹配
元字符和反义:
代码 | 解释 | 示例 | 说明 |
---|---|---|---|
. | 匹配除换行符以外的任意字符 | b.t | 可以匹配到but,b#t,b1t |
\w | 匹配字母或数字或下划线或汉字 | b\wt | 可以匹配bat,b1t,b_t等 但不能匹配b#t |
\W | 匹配任意不是字母,数字,下划线,汉字的字符 | b\Wt | 可以匹配b#t / b@t等 但不能匹配but / b1t / b_t等 |
\s | 匹配任意的空白符 (包括\r、\n、\t等) |
love\syou | 可以匹配love you |
\S | 匹配任意不是空白符的字符 | love\Syou | 可以匹配love#you等 但不能匹配love you |
\d | 匹配数字 | \d\d | 可以匹配99 / 20 / 19等 |
\D | 匹配任意非数字的字符 | \D\d | 可以匹配到#9,!8等一个非数字,一个数字的字符 |
\b | 匹配单词的开始或结束 | \bThe\b | |
\B | 匹配不是单词开头或结束的位置 | \Bio\B | |
^ | 匹配字符串的开始 | ^th | 可以匹配到以th开头的字符串 如:the / this |
$ | 匹配字符串的结束 | se$ | 可以匹配到以se结尾的字符串 如:these / close |
[^x] | 匹配除了x以外的任意字符 | [^aeiou] | 匹配除了aeiou这几个字母以外的任意字符 |
[X] | 匹配X这个字母 | [aeiou] | 匹配aeiou这几个字母中的任意一个字符 |
| | 匹配 | 两边的任意一个 | dog|cat | 这里匹配到的内容是dog或者cat |
注意:
1.在使用两个中括号"[" "]"匹配内容时,中括号中的所有字符串都是字符串原来的意思,不需要转义。如:[^.|*]这里就是匹配托字符,或者点或者星号。
2. " | "它匹配的内容时它两边的整条规则,而不是它两边的某些字符。如果要匹配它两边的某些字符则要使用无捕获组' (?:) '包起来。比如要匹配 ‘I have a dog' 或者 ’I have a cat'。就需要写成r'I have a (?:dog|cat)'而不能写成r'I have a dog|cat'
转义字符
在上面也看到了,“ . ”和“ | ”和“ ^ ”等这些字符在正则表达式中已经有了特殊的含义了,你在查找它们的时候就有问题了。你没法指定它们,因为它们会被解释成其它的意思。这时你就需要使用" \ "来取消这些字符的特殊意义。因此,你应该使用" . "和" * "。当然,要查找\本身,你也得用" \ "。如果不使用“ \ ”来转义也可以使用" [ ] "将要转义的字符括起来达到使用本义的目的,只是这样做有一点麻烦,使用转义字符“ \ ”方便一点,当然如果有多个字符需要转义的时候使用" \ "将使整个表达式变得复杂。所以还有一种更简单的方法,就是在引号外加一个r,使用r后 ‘ ’ 中需要转义的字符就会自动转义(双引号中的双引号除外)。
例如:deerchao.net匹配deerchao.net,要匹配c:\windows我们可以写成c:\windows或者r'c:\windows'。
分组
代码 | 解释 | 示例 | 说明 |
---|---|---|---|
(exp) | 匹配exp并捕获到自动命名的组中 | ||
(?<name>exp) | 匹配exp并捕获到名为name的组中 | ||
(?:exp) | 匹配exp但是不捕获匹配的文本 | I have a (?:dog|cat) | 匹配的结果为I have a dog 和I have a cat |
零宽断言
代码 | 解释 | 示例 | 说明 |
---|---|---|---|
(?=exp) | 匹配exp前面的位置 | \b\w+(?=ing) | 可以匹配I’m dancing中的danc |
(?<=exp) | 匹配exp后面的位置 | (?<=\bdanc)\w+\b | 可以匹配I love dancing and reading中的第一个ing |
(?!exp) | 匹配后面跟的不是exp的位置 | ||
(?<!exp) | 匹配前面不是exp的位置 | ||
(?#comment) | 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读 |
注意:要包含注释的话,最好是启用“忽略模式里的空白符”选项,这样在编写表达式时能任意的添加空格,Tab,换行,而实际使用时这些都将被忽略。启用这个选项后,在#后面到这一行结束的所有文本都将被当成注释忽略掉。
次数匹配
代码 | 解释 | 示例 | 说明 |
---|---|---|---|
* | 重复零次或更多次 | \w* | 表示字母数字下划线可以出现任意次 |
+ | 重复一次或更多次 | \w+ | \w匹配到的内容至少出现一次 |
? | 重复零次或一次 | \w? | \w匹配到的内用出现一次或零次 |
{n} | 重复n次 | \w{3} | \w匹配到的内容出现3次 |
{n,} | 重复n次或更多次 | \w{3,} | \w匹配到的内容至少出现3次 |
{n,m} | 重复n到m次 | \w{3,6} | \w匹配到的内容出现三到六次 |
*? | 重复任意次,但尽可能少重复 | ||
+? | 重复1次或更多次,但尽可能少重复 | ||
?? | 重复0次或1次,但尽可能少重复 | ||
{n,m}? | 重复n到m次,但尽可能少重复 | ||
{n,}? | 重复n次以上,但尽可能少重复 |
注意:当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。以这个表达式为例:a.*b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配。
有时,我们更需要懒惰匹配,也就是匹配尽可能少的字符。前面给出的限定符都可以被转化为懒惰匹配模式,只要在它后面加上一个问号?。这样.*?就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。现在看看懒惰版的例子吧:
a.*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字符)和ab(第四到第五个字符)。
为什么第一个匹配是aab(第一到第三个字符)而不是ab(第二到第三个字符)?简单地说,因为正则表达式有另一条规则,比懒惰/贪婪规则的优先级更高:最先开始的匹配拥有最高的优先权
附加
代码 | 解释 |
---|---|
\a | 报警字符(打印它的效果是电脑嘀一声) |
\t | 制表符,Tab |
\r | 回车 |
\v | 竖向制表符 |
\f | 换页符 |
\n | 换行符 |
\e | Escape |
这里只是大致说了一下正则表达式的匹配规则,在python中的具体使用还看下一篇Python之正则表达式运用
说明:以下内容是个人对Python中正则表达式的理解,如有不妥之处还望见谅。