python中,命令行和脚本等,里面都会对转义符号做处理,此时的字符串会和正则表达式的引擎产生冲突。即在python中字符串'\n'会被认为是换行符号,这样的话传入到re模块中时便不再是‘\n’这字面上的两个符号,而是一个换行符。所以,我们在传入到正则引擎时,必须让引擎单纯的认为是一个'\'和一个'n',所以需要分别加上转义符,成为'\\\n',针对这个情况,python中使用raw_input方式,在字符串前加上r,使字符串中的转义符不再特殊处理(即python中不处理,统统丢给正则引擎来处理),那么换行符就是r'\n'
1 | . #普通模式下,匹配除换行符外的任意字符。(指定DOTALL标记以匹配所有字符) |
1 | * #匹配前面的对象0个或多个。千万不要忽略这里的0的情况。 |
2 | + #匹配前面的对象1个或多个。这里面的重点是至少有一个。 |
3 | ? #匹配前面的对象0个或1个。 |
4 | {m} #匹配前面的对象m次 |
5 | {m,n} #匹配前面的对象最少m次,最多n次。 |
1 | ^ #匹配字符串开头位置,MULTILINE标记下,可以匹配任何\n之后的位置 |
2 | $ #匹配字符串结束位置,MULTILINE标记下,可以匹配任何\n之前的位置 |
01 | \m m是数字,所谓的反向引用,即引用前面捕获型括号内的匹配的对象。数字是对应的括号顺序。 |
02 | \A 只匹配字符串开头 |
03 | \b 可以理解一个锚点的符号,此符号匹配的是单词的边界("单词边界符")。这其中的word定义为连续的字母,数字和下划线。 |
04 | 准确的来说,\b的位置是在\w和\W的交界处,当然还有字符串开始结束和\w之间。 |
05 | \B 和\b对应,本身匹配空字符,但是其位置是在非"边界"情况下,比如r'py\B'可以匹配python,但不能匹配'py,','py.' 等等 |
06 | \d 匹配数字 |
07 | \D 匹配非数字 |
08 | \s 未指定UNICODE和LOCALE标记时,等同于[ \t\n\r\f\v],注意\t之前是一个空格,表示也匹配空格。 |
09 | \S 与\s相反 |
10 | \w 未指定UNICODE和LOCALE标记时,等同于[a-zA-Z0-9_] |
11 | \W 和\w相反 |
12 | \Z 只匹配字符串的结尾 |
1 |
1 | (...) 普通捕获型括号,可以被\number引用。 |
1 | (?aiLmsx) |
2 | a re.A |
3 | i re.I #忽略大小写 |
4 | L re.L |
5 | m re.M |
6 | s re.S #点号匹配包括换行符 |
7 | x re.X #可以多行写表达式 |
01 | (?:......) #非捕获型括号,此括号不记录捕获内容,可节省空间 |
02 | (?P<name>...) #此捕获型括号可以使用name来调用,而不必依赖数字。调用时使用(?P=name) |
03 | (?#...) #注释型括号,此括号完全被忽略 |
04 | (?=...) #lookahead assertion 如果后面是括号中的,则匹配成功 |
05 | (?!...) #negative lookahead assertion 如果后面不是括号中的,则匹配成功 |
06 | (?<=...) #positive lookbehind assertion 如果前面是括号中的,则匹配成功 |
07 | (?<!...) #negative lookbehind assertion 如果前面不是括号中的,则匹配成功 |
08 | #以上<span><b>四种类型断言</b></span>,本身均不匹配内容,只是告知正则引擎是否开始匹配或者停止。 |
09 | #另外在后两种后项断言中,必须为<b>定长断言</b>。 |
10 | (?(id/name)yes-pattern|no-pattern) |
11 | #如有由id或者name指定的组存在的话,将会匹配yes-pattern,否则将会匹配no-pattern,通常情况下no-pattern也可以省略。 |
如'??'会优先匹配没有的情况,然后才是1个对象的情况。而{m,n}?则是优先匹配m个对象,而不是占多的n个对象。
首先放在最前面,python属于perl风格,属于传统型NFA引擎,与此相对的是POSIX NFA和DFA。所以大部分讨论都针对传统型NFA
NFA是基于正则表达式主导的引擎,同时,传统型NFA引擎会在找到符合状态的情况下立即停止。即得到匹配之后就停止引擎。相对来说,POSIX NFA 中不会立刻停止,其会在所有可能匹配的结果中寻求最长结果。这也是有些bug在传统型NFA中不会出现,但是放到后者中,会出现无法结束的情况。
引申一点,NFA学名为”非确定型有穷自动机“,DFA学名为”确定型有穷自动机“
这里的非确定和确定均是指被匹配的目标文本中的字符来说的,在NFA中,每个字符在一次匹配中即使被检测通过,也不能确定他是否真正通过,因为NFA中会出现回溯!甚至不止一两次。图例见后面例子。而在DFA中,由于是目标文本主导,所有对象字符只检测一遍,到文本结束后,过就是过,不过就不过。这也就是”确定“这个词的来历。
1 | 1,在是进行尝试还是跳过尝试时,匹配优先量词和忽略优先量词会作出相应决定。 |
2 | 2,匹配失败时,回溯需要返回到上一个备用状态,原则是后进先出(LIFO) |
以上的例子引发了一个匹配时的思考,我们尽量避免使用'.*' ,因为其总是可以匹配到最末或者行尾,既然我们只寻求引号之间的数据,往往可以借助排除型数组来完成工作。此例中,使用'[^'']*'这个的作用显而易见,我们只匹配非引号的内容,那么遇到第一个引号即可退出*号控制权。
1 | '\w+:' |
这个匹配的情况是这样的,会优先去匹配所有的符合\w的字符,然后假如字符串的末尾没有:,即匹配未找到冒号,此时触发回溯机制,他会迫使前面的\w+释放字符,并且在交还的字符中重新尝试与':'作比对。但是问题出现在\w是不包含冒号的,显然无论如何都不会匹配成功,但是依照回溯机制,就会造成无谓的比对,这是对资源的浪费。所以我们就需要避免这种回溯,对此的方法就是将前面匹配到的内容固化,不令其存储备用状态,那么引擎就会因为没有备用状态可用而结束匹配过程。大大减少回溯的次数。
虽然python中不支持,但书中提供了利用前向断言来模拟固化过程。
1 | (?=(...))\1 |
1 | '(?=(\w+))\1:' |
1 | 1,在相对的应用中,在结果保证正确的情况下,应该优先的去匹配更可能出现的结果。即将可能性大的分支尽可能放在靠前。 |
2 |
2,多选结构的代价。不能滥用多选结构,因为当匹配到多选结构时,缓存会记录下相应数目的备用状态。举例子如:[abcdef]和‘a|b|c|d|e|f’这两个表达式很可能经过稍
0 有用
0 无用
热门标签相关文章周热点月热点
Copyright ©2011-2012 360ITO技术社区 All Rights Reserved.
| 关于
| 联系我们
| 杭州精创信息技术有限公司
浙ICP备09019653号-26|
|
共有0个评论 我要评论»
网友回复/评论仅代表其个人看法,并不表明本社区同意其观点或证实其描述。
1.不欢迎无意义的回复/评论和类似“顶”、“沙发”之类没有营养的文字
如果只是想简单的表个态,请点 有用无用支持反对 等按钮
2.发言之前请再仔细看一遍文章,或许是您遗漏、误解了,理性讨论、切莫乱喷
3.严禁发布违法、违规的信息,请勿到处招贴广告、发布软文;
4.如果您发现自己的回复/评论不见了,请参考以上3条
5.不停制造违规、垃圾信息的,账户将被禁止