总结一下最近学的正则化知识,里面有一些自己的理解。如果有错,欢迎讨论。
概念捋清:我的理解是正则化表达是通过一组符号表达一种字符串组织结构,相当于用一个表达式表示了一个字符串组合的集合。
首先考虑单个匹配,从表达式的基本符号开始着手。
1.非重复选择:
系统给定选择:\d 数字,\s 空格,\w 字母或者数字 . 任意字符。把小写变大写代表非,比如\D表示非数字
自定义选择:1.1 | 表或,如ac|bc,[abc] 表示这个位点字符为方括号中的一个,括号内字符串是拆开了或的关系,在[]中加入^表示非。
注:字符串或者表达式有位置关系,而或是没有位置关系的,比如原字符串为ac,考虑[c,b]|[a,b],其实效果与[a,b,c,d]一样,^只能在[]里表示非的意思
2.重复选择:
系统给定选择:?0或1次,+ 次数大于等于1 ,*任意次数。
注:?在正则化中通常表示要进行一些特殊操作
注:通常匹配的时候都是贪婪模式,即会输出匹配最多的情况,如原字符串为abbbbb,正则表达式为ab+,则会输出abbbbb,加上?后变为非贪婪模式,如ab*?,输出为ab
自定义选择:a{n} a重复n次,a{n,m} a重复 n到m 次。
字符串组合重复:使用(),如(ab){3}
注:在re函数中,括号还有分组的意思,如果想要取消分组,公式为(?:string),如(?:abc){3},具体后面探讨。
3.位置确定:
每行的:^开头 $结尾
全文性质的:\A 开头 \Z 结尾
分隔:\b 大写为非的意思
注:在使用re.search('\ba','a a').group()的时候报错,改为re.search(r'\ba','a a')后成功。
为什么要用 r'\ba'或‘\\ba’才能在‘a a’中匹配出a?
正则表达式匹配反斜杠"\",为什么是"\\\\"或是 r"\\"呢?
因为在正则表达式中\为特殊符号,为了取消它在正则表达式中的特殊意义需要加一个\就变成了\\,但是问题又来了,\也是字符串中的特殊字符,所以又要分别对两个\取消其特殊意义,即为\\\\。Python中有一个原始字符串操作符,用于那些字符串中出现特殊字符,在原始字符串中,没有转义字符和不能打印的字符。这样就可以取消了\在字符串中的转义功能,即r"\\"。也就是说\b并不是正则表达式的命令,而是字符串的命令?正则表达式中的\和字符串中的\在命令出现重叠的时候是不一样的,正则表达式在更底层,要后进行转意,也就是先生成字符串,再在字符串的基础上进行正则表达,‘\ba’生成字符串就是退格a,需要再加一个\,这样生成的字符串才是\ba,如果命令不重叠就会直接生成\,可以尝试print ‘\dr’,结果为'\dr'.那么r‘’转的到底是字符串的转意还是正则化的转意?考虑r‘\ba’,作用在1a上,如果去掉的是正则化转意应该没有输出,所以去掉的应该是字符串的,但是这样有一个逻辑缺陷,如果‘\ds’是先变成字符串再用正则化表示,'\ds'是's',那么‘s’应当可以用‘\ds’输出,但是用程序表示出来会报错,个人理解是为了实现对字符串所有结构的识别,字符串中的\d被编译成了其他的编码,从这个角度出发,‘\ds’ 字符串应该可以用'\ds'识别,re.search('\ds','\ds').group(),结果为‘\x08s’,所以这个理解应该是对的。
4.分组
(?P<name>) 把括号内匹配定为name组(原有排序组名仍在)
/number 引用第number组的字符串,如原字符串‘1a2a2’,'(\d)a\1',会输出2a2
(?p=name)引用name组的字符串,
5.其他
(?mode)string 表示用某种模式对后面string进行匹配
6.条件选择
a(?=string)表示a后为string表达式,但是该位置不输出,相当于一个条件选择,如a(?='b'),输出后面为b的a
a(?!)和上面相反
a(?<=)a之前的内容匹配后才能输出
a(?<!)和上相反
(?(name)true|false)如果name组的字符串匹配到了就要匹配true表达式, 否则匹配false表达式。
先到这,有空继续补
re核心函数
findall
match
search
compile
sub
split