想阅读世界上所有最好的正则表达式吗? 做梦,年轻,你想要什么,就尽力学习。
js已经学习和使用了差不多一两年了,找到什么东西就会用到对象,继承一些东西就可以上手了,但是看看别人的框架**,总是随时卡住,有一个主要原因,那就是一串火星词(正则表达式)看不懂,学习什么,就是检查和补空,不怕你不懂,怕你以为什么都懂了。在开始做生意之前,让我们推荐一个软件:regexbuddy,无论是进行定期测试还是过程研究,它都是一个强大的工具。
语法复习,重点关注三条知识:贪婪匹配(?0==1, * any) 与那些相关的限定符 (,) 特殊字符: = ! / (
火星文字,基本上就是由它们组成的,为了配合汉字的原意,在特殊汉字之前加上字面意思,需要加上新的声明; 非捕获元字符:?:=(远期预测), ?阴性预检);回想起来,之前的人物匹配,基本上都和他有关; 其他,什么字符边界,括号,括号等; 正则表达式解析原理:这里暂时还没能写出来,先推荐一篇了解贪婪匹配的文章,正则表达式的日常应用基本满意,在菜鸟教程语法的开头已经详细提到过了,比如有一个正则表达式:chapter[1-9], 这个字符串我们只能匹配 chapter1-chapter9,也就是章节的一级标题,但是如果我们要匹配二级或者 **title 呢,这里我们用贪婪匹配,就是最大化目标字符串中的匹配结果,把之前的正则表达式:chapter[1-9] 改成 chapter[1-9],这样我们就可以匹配 chapter1, 第 12 章和第 123 章。但是如果我们把它改成/chapter[1-9]?/
这是无论如何/chapter
由于输入了多个数字,因此最多只能匹配一个数字,即 chapter1,但与原始表达式不同的是,此表达式也可以匹配裸章节,称为 (x?)。 ),问号前面的 x 可以出现 0 次或 1 次,当我们将其更改为/chapter[1-9]
星号(避免 markdown 语法),这可以在最后到达吗? 常见的结果,也称为,发生任意次数。 我们也可以通过 [n,m] 使用上面的内容,即 n=另一个与贪婪匹配配对的称为惰性匹配,所有前面出现的贪婪匹配后面都跟着一个? ,使整个表达式变成一个惰性匹配,可以理解为最小化匹配,例如 chapter[1-9] 匹配 chapter12345,结果是 chapter12345,但 chapter[1-9] ? 比赛结果是chapter1; 第[1-9]章是第1234章,第[1-9]章? 结是第1234章,称为最小化取消匹配结果并采取下限,通常称为懒惰模式。
你之前看到了什么? :,=,?!用得少的时候没注意,最近经常在大范围内看到它,吓得之前在读吞口时遇到过一个正则表达式:-[0-9a-f]-?(匹配 app-7ef5d9ee29。css expressions),一头扎进去,'-?'到底有什么特别的意思,最后我才发现,那是贪婪的匹配,你是个傻子,但是我真的不明白源码作者在想什么,可能我没有遇到app-7ef5d9ee29-any。CSS的'-?'你在干嘛,让我直接跳进坑里。
回到正题,我们先来了解一下什么是捕获组,可以用括号的形式概括为'(pattern)',匹配满足括号。 让我们看一下 rookie 教程中的一个定义:
四种形式,加上? 捕获元素和非捕获元素有什么区别,表现就是用exec方法进行匹配,将捕获组简单地存储在一组变量中。 理论太无聊了,看看例子就知道了,**在js中设置了page106高,略有改动:
var str ='mom and dad and baby';var pattern = /mom( and dad( and baby))/;捕获元形式 var pat= mom(?:and dad(?:and baby))/;非捕获元形式 var mat = patternexec(str);var match = pat.exec(str);console.log(mat);console.log(match);
看着devtools打印的结果,是不是有点让人瞠目结舌,是啊,虽然匹配结果一致,但是当捕获组匹配时,符合捕获元形式的单位会单独保存为匹配结果,非捕获元素不会单独保存,只保存完整的匹配结果。 我们共同的正则表达式$1、$2 实际上是对捕获组结果的引用。
捕获元素和非捕获元素已经弄清楚了,即(?:p attern) 和 (?=模式)有什么区别,答案,两个区别。区别 1:前者匹配的结果包含捕获元素,而后者的结果则不包含捕获元素。 区别 2:当前者与捕获元匹配时,它消耗字符(索引),而后者则不。 让我们看一个例子:
var str ='ababa';var pattern = /ab(?:a)/g;var pat= /ab(?=a)/g;var mat = pattern.exec(str);var match = pat.exec(str);console.log(mat);console.log(match); mat = pattern.exec(str);全局模式,第二场比赛 match = patexec(str);全局模式,第二个比赛控制台log(mat);console.log(match);
从上面**运行的截图中,可以看出区别之一,那就是(?:p attern) 保存在最终结果中,而 (?=pattern);区别不是很明显,我们需要依靠正则表达式好友,在这个过程中到底发生了什么? 看看运行的截图,如果你足够细心的话,你就能发现其中的区别,第一次匹配到结果,第二次开始匹配,?: 来自字符索引 3 和 ? = 来自 2,这就是我们之前所说的关于使用字符与不使用字符的内容。
好吧,最后一个问题,FCL预检(?=pattern) 和负预检查 (?!模式),事实上,仅从中文来理解否定预审会带来歧义。这里的负方向其实只是对正预检的否定,即为了匹配结果而对待匹配的字符不满足捕获条件。