Python 正则表达式
正则表达式在处理字符串时具有很高的效率,特别是字符串比较长时,python中正则表达式是必须要掌握的内容,尤其是做数据处理时。
元字符
正则表达式中使用英文句点对换行符之外的任意字符进行匹配,但是注意一个句点只能匹配一个字符,比如’.ython’可以与’python’和’jython’都匹配,但是与’cpython’、’ython’等字符是不匹配的。句点可以与换行符之外的所有字符匹配,因此称为通配符。另外还有一些元字符:
- \w 匹配字母或者数字或者下划线或汉字
- \W 匹配任意不是字母、数字、下划线、汉字的字符等价于[^A-Za-z0-9_]
- \s 匹配任务空白符,包括空格、制表符、换页符等
- \S 匹配任意不是空白符的字符,等价于[]
- \d 匹配数字
- \D 匹配任意非数组的字符 [^0-9]
- \b 匹配单词的开始或者结束
- \B 匹配不是单词开头或者结束的位置
特殊字符转义
字符串中可能存在特殊字符,比如要匹配’python.org’这个字符串时,就不能直接使用’python.org’进行匹配,因为被匹配的字符串中存在特殊字符’.’,这个句点本身就是通配符,需要特殊处理,即要对其进行转义,在前面加上转义符号’\’,这样上面的例子就应该使用’python\.org’来匹配想要的字符串’python.org’。
细心的同学可能发现了这里用了两个’\’,这是应为这里的转义分两层,第一层是解释器的转义,第二层是python的re模块的转义,如果只写一个’\’,那么’.’就会被当做一个整体传递给re模块,这有可能会造成内容的丢失,因此需要写两个’\’。如果不想要写连个’\’,Python中可以这样做,r’python.org’,使用原字符串。
字符集
字符集匹配是使用一个方括号’[]’来创建一个字符集进行匹配的,比如’[pj]thon’与’python’和’jython’都匹配,但是不与其他字符匹配,再比如’[A-Z]’与A到Z之间的任意字符都可以匹配,当然字符集还可以多订以一些匹配项比如’[a-zA-z0-9]’代表匹配所有小写字母、大写字母和数字,但是注意,字符集只能匹配到一个字符。如果要排除某些字符,可以在开头或结尾加上一个^(从开头匹配)或者$(从结尾开始匹配),比如’[^abc]’表示匹配除a、b、c之外的其他任意字符。
二选一和子模式
如果只想匹配连个字符串中的一个比如’python’和’perl’,该怎么办呢?这时可以考虑使用二选一模式,正则表达式使用的是管道字符’|’,表达式就是’python | perl’。
有时不想让二选一运算符用于整个模式,只是想用于模式的一部分,这时可以将二选一模式作为子模式放在圆括号内,上面的例子就可以改成’p(ython|perl)’,单个模式也可以是子模式。
可选模式和重复模式
在子模式后面加上问号,可指定为可选的,即可以包含也可以不包含。比如:1
r’(http://)?(www\.)?python\.org’
这个表达式表示可以匹配到包括或者不包括’http://’和’www.’的’python.org’字符串,有以下四种情况都可以匹配到:1
2
3
4'http://www.python.org'
'http://python.org'
'www.python.org'
'python.org'
这里面对org前面的句点进行了转义,防止其充当通配符。为了少使用’\’这里使用了原字符串的格式,另外每个可选的子模式都在圆括号内包含,这些子模式都是可有可无的。
基于上面的例子,如果想要匹配多个’www.’或者’http://’该怎么做呢?可以使用’*’或者’+’。具体是这样的:
- (pattern)* : pattern 可重复0、1或多次。
- (pattern)+ : pattern 可重复1或多次。
- (pattern){m,n} :模式可从父 m ~ n 次。
例如,r’w*.python.org’ 与 ‘www.python.org'匹配,也与'.python.org' 、 ‘ww.python.org’和’wwwwwww.python.org'匹配。同样,r'w+\.python\.org'与'w.python.org'匹配,但与 ‘.python.org’不匹配,而r’w{3,4}.python.org’只与’www.python.org'和'wwww.python.org'匹配。
贪婪与懒惰模式
当我们使用’.*’进行匹配时,会匹配任意非换行的字符,这有时候可能不会是我们想要的效果,比如
r’aabab’,中我们想要匹配出aab,那么使用’a.*b’对其进行匹配时,返回的结果时aabab,不是我们想要的结果,这是因为在匹配时.*是贪婪匹配模式,会一直匹配到最后的字幕b,要想返回我们想要的aab,必须进行懒惰模式的匹配,即匹配到一个字幕b时就停止匹配。懒惰模式是通过加上一个’?’来实现的。
使用‘a.*?b’就可以匹配到我们想要的aab啦。
2018.08.16新增(来自廖雪峰java基础课程,正则表达式部分)
廖雪峰总能通俗易懂地把内容讲出来,还是厉害。
正则表达式匹配规则:
正则表达式 | 规则 | 可以匹配 |
---|---|---|
A | 指定字符 | A |
\u548c | 指定Unicode字符 | 和 |
. | 任意字符 | a, b, &, 0 |
\d | 0-9 | 0, 1, 2, …, 9 |
\w | a-z, A-Z, 0-9, _ | a, A, 0, _, … |
\s | 空格,Tab键 | ‘ ‘, ‘ ‘ |
\D | 非数字 | a, A, &, _, … |
\W | 非\w | &, @, 中, … |
\S | 非\s | a, A, @, _, … |
AB* | 匹配任意个数字符 | A,AB, ABB, ABBB, … |
AB+ | 至少一个字符 | AB, ABB, ABBB, … |
AB? | 0个或1个字符 | A,AB |
AB{3} | 指定个数字符 | ABBB |
AB{1, 3} | 指定范围个数字符 | AB, ABB, ABBB |
AB{2, } | 至少n个字符 | ABB, ABBB, … |
AB{0, 3} | 最多n个字符 | A, AB, ABB, ABBB |
复杂规则:
正则表达式 | 规则 | 可以匹配 |
---|---|---|
^ | 开头 | 字符串开头 |
$ | 结尾 | 字符串结束 |
[ABC] | […] 内任意字符 | A, B, C |
[A-F0-9xy] | 指定范围的字符 | A, …, F, 0, …, 9, x, y |
[^A-F] | 指定范围外的任意字符 | 非A, …, F |
AB|CD | AB或CD | AB, CD |
AB|CD|EFG | AB或CD或EFG | AB, CD, EFG |