前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JS正则表达式正向前瞻习题引发的思考

JS正则表达式正向前瞻习题引发的思考

作者头像
IMWeb前端团队
发布2019-12-03 16:26:33
7240
发布2019-12-03 16:26:33
举报
文章被收录于专栏:IMWeb前端团队

本文作者:IMWeb wonghan 原文出处:IMWeb社区 未经同意,禁止转载

一、前言

最近在做正则表达式的习题,题目本身不难,但我做完习题后难免脑洞大开举一反三,而这次,被我自己的脑洞难住了。

题目如下:当你收到一串HTML代码,需要对这一串HTML代码过滤,将里面所有的非<p >标签都改为<p>标签

如果不了解 正向前瞻 或者 对这道题目没有什么头绪 ,可以看下面这篇文章。

附参考文献地址:https://www.cnblogs.com/dong-xu/p/6926064.html

因此一般解题的代码为:

代码语言:javascript
复制
var str = '<p>,</p>,</a>,</ p>';
var reg = /<(\/?)(?!p|\/p).*?>/g;
var newStr = str.replace(reg, "<$1p>");
console.log(newStr);
//<p>,</p>,</p>,</p>

二、疑问

我不禁产生疑问:如果将reg改为:

代码语言:javascript
复制
var reg = /<(\/?)(?!p).*?>/g;

按照逻辑分析来说,结果也是一样的。但是,结果却大跌眼镜:

代码语言:javascript
复制
var str = '<p>,</p>,</a>,</ p>';
var reg = /<(\/?)(?!p).*?>/g;
var newStr = str.replace(reg, "<$1p>");
console.log(newStr);
//<p>,<p>,</p>,</p>

可以看出,位于第二项的“</p>”变成了“<p>”。如果从逻辑上分析,如果“<(\/?)”对应“</”的情况下,因为"</"后面是“p”,所以最终不会被匹配到的(......①),但结果却不符。

因此便产生了疑问:为什么会这样?若您也有相同疑问,且慢慢往下看。


三、分析

借助https://regex101.com/ 我们来慢慢分析一下

可以看出,</p>被匹配到,让我们简化一下正则表达式分析一下:

可以看出,位于第二项的“</p>”:“<(\/?)”对应“<”而不是“</”,因此后面是“/p”而不是"p"(符合断言“(?!p)”),而再后面的“.*?”即对应"/p",最后的“>”对应“>”。(......②)

*是否会产生疑问:以上的情况(......①)(......②),逻辑分析上来说均是说得通的,但正则表达式偏偏选择第②种情况,这是为什么呢?

其实,不妨看看网站右边的词条解释

可见,正则表达式按照字符匹配,先匹配"<",再匹配“(\/?)”,之后匹配“(?!p)”,然后匹配“.*?”,最后匹配“>”。

其中,造成以上疑问的罪魁祸首是“?”,看看词条的解释:“? Quantifier — Matches between zero and one times, as many times as possible, giving back as needed (greedy)”。意思是:在“/”出现0次或1次这两种情况下匹配,判断各情况下的匹配情况,然后返回符合匹配且是贪婪匹配的情况(默认情况下是贪婪匹配)

1.以</p>为例,分2种情况讨论:

(1)匹配“<” --> "/"出现0次 --> "/p”不是“p”,符合断言 -->符合匹配;

(2)匹配“<” --> "/"出现1次 --> "p”等于“p”,不符合断言 -->不符合匹配;

因此,可得出结论:选择情况(1),与实际测试结果符合。

1.以</a>为例,分2种情况讨论:

(1)匹配“<” --> "/"出现0次 --> "/a”不是“p”,符合断言 -->符合匹配;

(2)匹配“<” --> "/"出现1次 --> "a”不是“p”,符合断言 -->符合匹配;

因此,根据贪婪匹配原则,选择情况(2),与实际测试结果符合。


四、总结

正则表达式的基本语法、属性与方法、分组与捕获、引用与反向引用、贪婪匹配与惰性匹配、正向前瞻与负向前瞻、String方法的正则用法等,需要在理解的基础上,融会贯通,才能更好的掌握。

若对正则表达式有疑问便借助:https://regex101.com/ 进行分析。

愿你我在前端之路上昂首向前,共同进步。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-01-28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、前言
  • 二、疑问
  • 三、分析
  • 四、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档