背景
正则表达式(regular Expression)是计算机中的概念。regular这里是规则、规律的意思,字面翻译指的是:规则的表达式。正则表达式主要用来处理字符串的工具,拥有自己独特的语法。 计算机常用语言均支持正则表达式,语法都是相同的,区别在于不同的语言支持的语法略有差异。
在数据科学实践中,特别是文本数据分析中,由于实际文本数据的纷繁复杂,正则表达式就成为文本检索分析的重要工具。本篇介绍以python语言背景来介绍正则表达式的实现。
https://jex.im/regulex/#!flags=&re=%5E(a%7Cb)*%3F%24
第一章 正则表达式字符匹配
正则表达式可以理解为一种字符串模式识别,识别对象有两个:子字符串、子字符串位置。
python中内置正则表达式包,直接import re。比如下面实现一个精确匹配:
1 | import re |
1.1 两种模糊匹配
正则表达式的强大主要实现模糊匹配,主要有:横向模糊匹配、纵向模糊匹配。
1、横向模糊匹配
定义:正则匹配的字符串的长度不是固定的。
举一个栗子:
我们需要匹配字符串中具有特有的模式子串:第一个字符是’a’,最后一个字符是‘c’,中间部分长度可变,但是均为’b’,数量范围为[2,3]。具体代码实现如下:
1 | import re |
注意findall函数是全局匹配,即按顺序遍历字符串进行匹配。
2、纵向模糊匹配
定义:正则匹配的字符串,存在一些位置的值不固定。
举个栗子:
我们需要匹配字符串具有的模式为:第一个和最后一个字符为‘a’、’b’,中间部分长度为1,但是字符可选,备选集合为:{b,c,d} 。代码实现如下:
1 | import re |
正则表达式匹配的主要模式就是横向模糊、纵向模糊及两种模式的组合。
1.2 字符组
这里字符组其实匹配的是单个字符,并不是“组”哈。
范围表示方法
例如在纵向模糊中我们举的例子,用[b,c,d]表示这三个字符的其中一个。在实际中如果备选集合比较大怎么办?有简略的表达式,比如:
1 | # [0,1,2,3,4,5,6,7,8,9] 等价表示为[0-9] |
上面范围表达式,会被自动解析为连续字符。
有些杠精要问了假如备选集合中有横杆字符’-‘字符咋办,比如{‘a’,’-‘,’c’},这时候我们不能写写成这样了。要这样写:[-ac]、[ac-]、[a\-c],注意这里的转义符: ‘\’,后续我们再介绍。
排除字符组(反义字符组)
在纵向模糊匹配中,还有一种匹配模式:某个字符除了在排除集中的字符,可以是任意字符。
1 | # 例如[^abc],表示一个除"a"、"b"、"c"之外的任意一个字符。字符组的第一位放^(脱字符),表示求反的概念。 |
最后我们介绍简写形式,即解析语义约定俗成的简短写法。
\d就是
[0-9]
。表示是一位数字。记忆方式:其英文是digit(数字)。\D就是
[^0-9]
。表示除数字外的任意字符。\w就是
[0-9a-zA-Z_]
。表示数字、大小写字母和下划线。记忆方式:w是word的简写,也称单词字符。\W是
[^0-9a-zA-Z_]
。非单词字符。\s是
[ \t\v\n\r\f]
。表示空白符,包括空格、水平制表符、垂直制表符、换行符、回车符、换页符。记忆方式:s是space character的首字母。\S是
[^ \t\v\n\r\f]
。 非空白符。.就是
[^\n\r\u2028\u2029]
。通配符,表示几乎任意字符。换行符、回车符、行分隔符和段分隔符除外。
1.3 量词
简写形式
量词即连续重复的字符模式。
{m,n}
表示至少出现次数范围为:大于等于m,小于等于n。{m,}
表示至少出现m次,即{m,+infinity}。{m}
等价于{m,m}
,表示出现m次。?
等价于{0,1}
,表示出现或者不出现。记忆方式:问号的意思表示,有吗?+
等价于{1,}
,表示出现至少一次,即{1,+infinity}。*
等价于{0,}
,表示出现任意次,即{0,+infinity}。
贪婪匹配和惰性匹配
先看一个栗子:
1 | import re |
上面的正则表达式会匹配连续出现的数值型字符串,长度范围为:2,3,4,5。这种模式是贪婪模式,即尽可能的匹配到最长范围。
而对应的由惰性匹配,即尽可能少的匹配:
1 | import re |
量词组通过问号实现惰性匹配,还有其他情况:
{m,n}?
{m,}?
??
+?
?
记忆技巧:问号的含义是反问:还不知足吗?意思就是要惰性一点。。。。
1.4 多选分支
一个模式可以实现横向和纵向模糊匹配。而多选分支可以支持多个子模式任选其一。
具体形式如下:(p1|p2|p3)
,其中p1
、p2
和p3
是子模式,用|
(管道符)分隔,表示其中任何之一。
例如要匹配”good”和”nice”可以使用/good|nice/
。测试如下:
1 | import re |
也就是说,分支结构也是惰性的,即当前面的匹配上了,后面的就不再尝试了。
1.5 案例分析
匹配时间字符串
例如需要匹配字符串中24小时制的时间字符串,比如:10:30,23:59
1 | import re |
第二章 正则表达式位置匹配
正则表达式属于模式匹配,主要两种匹配目标:字符和位置。
字符串的位置
位置定义:相邻字符之间的位置。
锚字符
Python中的锚字符
^(脱字符)和$(美元符)
^(脱字符),用来匹配字符串开头。多行模式下,匹配每行的开头位置。
$(美元符),用来匹配字符串结尾。多行模式下,匹配每行的结尾位置。
举个栗子:
第三章 正则表达式括号的作用
第四章 正则表达式回溯原理
第五章 正则表达式的拆分
第六章 正则表达式的构建
第七章 正则表达式的性能调优
第八章 Python的正则表达式处理函数
写在最后
参考文献
1、