正则基础教程一些冷门的知识

  

正则基础教程一些冷门的知识
正则引擎
正则分几种引擎也从是本书获得的知识点之一。
DFA
传统型NFA POSIX NFA

NFA范围更广,例如JAVA、PHP、Ruby、。net……你是看不起我javascript所以才不列入的吗?
使用DFA的是flex, MySQL, lex, awk大部分版本…实话说,除了MySQL,都没听过,不过不用在意!

  

两个引擎的区:
NFA更注重表达式
DFA文本主导
通过书中里例子说,NFA用表达式来匹配文本,而DFA是文本来匹配文表达式。当写好一个正则之后,NFA是先检查表达式,同时检查文本是否匹配这个表达式。而DFA则是先扫描文本,然后处理表达式中的所有匹配可能,如果匹配失败,就将这条可能的线,淘汰。所以这里衍生一个概念就是回溯,NFA有回溯,而DFA没有。

  

知识点
作为一个菜鸟,正则表达式一直是书到用时方恨少的角色。平时都是能抄则抄,不能抄的时候干着急,只能用字符串的子串,indexOf, chatAt等等的方法实现功能,既不优雅也不够装逼。上网学习也都是菜鸟教程,W3school。然后下面说一下以上两个基础教程里没说到的知识点。

  

括号捕获与反向引用
当你在正则表达式里使用了(),在表达式匹配时,它能记住或者说缓存括号内匹配的结果,从而可以拿到括号内的结果,可以重复使用或者只需要括号内的结果,来剔除不需要的匹配内容。

  

//我们经常会用匹配方法来匹配字符串,结果是一个数组,而不是最后的匹配结果,为什么呢?看下面的例子
“abc" .match (/(a) (b) (c)/)//(“abc",“a",“b",“c"]
“abc" .match abc (//)//[“abc"]
可以看的到,括号会缓存括号里匹配的内容,单独列出来,那么怎么拿到括号内的内容呢,而不是通过匹配返回的结果拿,因为有时候我们需要在表达式里使用捕获的值,从而达到匹配重复的内容。这部分就叫反向引用。

  

“abc-abc-cba" .replace (/(a) (b) c - 1 \ \ 2/?//c-cba
“abc-abc-cba" .replace (/(a) (b) c/g, 1美元2美元)//ab-ab-cba
RegExp。1美元//
RegExp。2美元//b
这里展示了两种使用反向引用的方法,一种是在表达式内通过1 \ \ 2的形式拿到两个缓存的值,一种是使用1美元2美元的形式拿到。因为正则是从左开始匹配的,所以(a)就是第一个捕获的匹配值,所以他是\ 1或是1美元,以此类推。

  

非捕获型括号
上面说了括号会捕获值,一般来说这样会影响性能,或者你会用到括号来做分组,但是不想捕获的情况,(?)非捕获型括号就是这么用的,那么重写一下上面的例子。

  

“abc-abc-cba" .replace (/(a) (?: b) c - 1 \ \ 2/?//匹配失败了,因为\ 2不存在
“abc-abc-cba" .replace (/(a) (?: b) c - \ 1/)//bc-cba
RegExp。1美元//
RegExp。2美元//啊?br/>环视

  

类型正则表达式
肯定逆序环视? & lt;=
否定逆序环视? & lt; !
肯定顺序环视吗?=
否定顺序环视吗? !=和
? !在菜鸟和w3school里有简单的提及,菜鸟里还提到这两个还能重写捕获,但是吗? & lt;=和? & lt; !并没有提及。

  

写几个演示表示一下:

  

//找一个字母,它紧跟在b前面
“abac" .replace (/(?=b)/g)//bac

  

//找到一个字母,它紧跟在一个不是b的字母前面
“abac" .replace (/(? ! b)/g)//abc

  

//接着是逆序环视
//找到一个字母,它跟在b后面
“abac" .replace (/(& lt;=b) a/g)//abc

  

//找到一个字母,他不跟在b后面
“abac" .replace (/(? & lt; ! b) a/g)//bac

  

//一个有趣匹配
//在a和b之间插入一个“,“
“abac" .replace (/(? & lt;=) (?=b)/g,“,“)//bac
可以看的出,环视是要和捕获括号一起用的,并且不会占用匹配字符,他只是检查表达式是否匹配。所以这就是重写捕获了。

  

忽略优先量词
量词匹配一般有三种 + ?然。而还可以写作, ?或+ ?,使匹配结果导向完全不同的结果。例子:

  

“abc-aaa-abc-abc" .replace (/abc -。* abc/")//啊?/p>   

“abc-aaa-abc-abc" .replace (/abc -。 ?abc/")//?abc"
?忽略优先会先忽略当前匹配的值,先匹配后面的abc,如果匹配失败,再匹配自己,而会优先匹配自己,等匹配结束之后,再从后面一点点吐出,回来匹配量词后面的表达式。从而造成以上不同的结果。知道这个之后,就不会再傻傻的把和?分开解读了。当然,具体情况具体分析,到底使用哪个。

  

回溯
回溯应该算是正则里的性能杀手了吧。如果表达式写的不好,造成过度的灾难性回溯,会导致执行时间指数级增长。

正则基础教程一些冷门的知识