js里如何正确理解正则表达式的回溯

这次给大家带来js里如何正确理解正则表达式的回溯,js里正确使用正则表达式回溯的注意事项有哪些,下面就是实战案例,一起来看一下。

在正则表达式实现中,回溯是匹配过程的基本组成部分,它是正则表达式如此好用和强大的根源。然而,回溯计算代价很高,如果设计失误,将导致失控。回溯是影响整体性能的唯一因素,理解它的工作原理,以及如何减小使用频率,可能是编写高效正则表达式的关键点

当一个正则表达式扫描目标字符串时,从左到右逐个扫描正则表达式的组成部分,在每个位置上测试能不能找到一个匹配。对于每一个量词和分支,都必须确定如何继续进行。如果是一个量词(如*、+?或者{2,}),那么正则表达式必须确定何时尝试匹配更多的字符;如果遇到分支(通过|操作符),那么正则表达式必须从这些选项中选择一个进行尝试。

当正则表达式做出这样的决定时,如果有必要,它会记住另一个选项,以备返回后使用。如果所选方案匹配成功,正则表达式将继续扫描正则表达式模板,如果其余部分匹配也成功了,那么匹配就结束了。但是,如果所选择的方案未能发现相应匹配,或者后来的匹配也失败了,正则表达式将回溯到最后一个决策点,然后在剩余的选项中选择一个。继续这样,直到找到一个匹配,或者量词和分支选项的所有可能的排列组合都尝试失败后放弃这一过程,然后移动到此过程开始位置的下一个字符上,重复此过程。

例如,下面的代码演示了这一过程是如何通过回溯处理分支的。

/h(ello|appy) hippo/.test("hello there, happy hippo");

登录后复制

上面一行正则表达式用于匹配“hello hippo”或“happy hippo”。测试一开始要查找一个h,目标字符串的第一个字母恰好就是h,立刻就找到了。接下来,子表达式(ello|appy)提供了两个处理选项。正则表达式选择最左边的选项(分支选择总是从左到右进行),检查ello 是否匹配字符串的下一个字符,确实匹配,然后正则表达式又匹配了后面的空格。

然而,在接下来的匹配中正则表达式“走进了死胡同”,因为hippo 中的h 不能匹配字符串中的下一个字母t。此时正则表达式还不能放弃,因为它还没有尝试过所有的选择,随后它回溯到最后一个检查点(在匹配了首字母h 之后的那个位置上)并尝试匹配第二个分支选项。但由于匹配没有成功,而且也没有更多的选项了,正则表达式认为从字符串的第一个字符开始匹配是不能成功的,因此它从第二个字符开始重新进行查找。正则表达式没有找到h,继续向后找,直到第14 个字母才找到,它匹配happy 的那个h。随后正则表达式再次进入分支过程,这次ello 未能匹配,但在回溯之后的第二次分支中,它匹配了整个字符串“happy hippo”,匹配成功了。

再如,下面代码演示了带重复量词的回溯。

var str = "

para 1.

" +"js里如何正确理解正则表达式的回溯" +"

Para 2.

" +"

p.

";/

.*

/i.test(str);

登录后复制

正则表达式先匹配了字符串开始的3个字母

,然后是.*。点号表示匹配除换行符以外的任意字符,星号这个“贪婪”量词表示重复零次或多次,匹配尽量多的次数。因为目标字符串中没有换行符,正则表达式将匹配剩下的全部字符串!不过由于正则表达式模板中还有更多内容需要匹配,所以正则表达式尝试匹配标签的。匹配返回成功需要从第一段头部一直扫描到最后一个的末尾,这可能不是我们想要的结果。

将正则表达式中的“贪婪”量词*改为“懒惰”(又名“非贪婪”)量词*?,以匹配单个段落。“懒惰”量词的回溯工作以相反方式进行。当正则表达式/

.*?/推进到.*?时,首先尝试全部跳过,然后继续匹配。

这样做是因为*?匹配零次或多次,尽可能少重复,尽可能少意味着可以重复零次。但是,当随后的得到完全匹配。

如果目标字符串只有一个段落,那么此正则表达式的“贪婪”版本和“懒惰”版本是等价的,但尝试匹配的过程不同。

当一个正则表达式占用浏览器几秒甚至更长时间时,问题原因很可能是回溯失控。为说明此问题,给出下面的正则表达式,它的目标是匹配整个HTML文件。此表达式被拆分成多行是为了适合页面显示。与其他正则表达式不同,JavaScript在没有选项时可使点号匹配任意字符,包括换行符,所以此例中以[sS]匹配任意字符。

/[sS]*?[sS]*?[sS]*?[sS]*?[sS]*?[sS]*?[sS]*?/

登录后复制

此正则表达式匹配在正常HTML 字符串时工作良好,但当目标字符串缺少一个或多个标签时,就会变得十分糟糕。例如

以上就是js里如何正确理解正则表达式的回溯的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2777618.html

(0)
上一篇 2025年3月8日 15:11:09
下一篇 2025年2月26日 20:39:51

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • JS实现网站悬浮广告的代码

    本文主要和大家分享JS实现网站悬浮广告的代码,大家可以先看一下效果图,希望能帮助到大家。 如图 黄色区块会沿着浏览器的上下左右碰撞移动,可关闭,鼠标移上去会停止 nbsp;html>广告*{pding:0px;margin:0px;}…

    2025年3月8日
    200
  • JS正则表达式验证数字的实战归纳

    这次给大家带来JS正则表达式验证数字的实战归纳,JS正则表达式验证数字的注意事项有哪些,下面就是实战案例,一起来看一下。 正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹…

    编程技术 2025年3月8日
    200
  • JS实现判断鼠标是否滚动的代码

    本文主要和大家分享js实现判断鼠标是否滚动,主要以代码的形式和大家分享,希望能帮助到大家。 var scrollFunc = function (e) { var direct = 0; e = e || window.event; if …

    编程技术 2025年3月8日
    200
  • JS里最基础的正则表达式使用详解

    这次给大家带来JS里最基础的正则表达式使用详解,在JS里使用基础正则表达式的注意事项有哪些,下面就是实战案例,一起来看一下。 正则表达式是一个很牛逼的东东,今天在这里只是简单的给刚刚接触JS的人普及一下,里面若有争议的地方欢迎大家留言! 1…

    2025年3月8日
    200
  • JS的正则如何校验非零的正整数

    这次给大家带来JS的正则如何校验非零的正整数,正则校验非零正整数的注意事项有哪些,下面就是实战案例,一起来看一下。 话不多说,请看实例代码 function validation() { var val = document.getElem…

    2025年3月8日 编程技术
    200
  • JS的正则如何校验非零的负整数

    这次给大家带来JS的正则如何校验非零的负整数,正则校验非零负整数的注意事项有哪些,下面就是实战案例,一起来看一下。 话不多说,请看代码 function validation() { var val = document.getElemen…

    编程技术 2025年3月8日
    200
  • AngularJS之前端框架

    本文主要为大家分享一篇JAngularJS之前端框架的请求方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧,希望能帮助到大家。 使用: 登录后复制登录后复制 一、常用属性:     ng-app:可以再任何元素上使用,代…

    编程技术 2025年3月8日
    200
  • js实现断点调试

    本文主要和大家分享js实现断点调试,主要以图文的形式和大家分享,希望能帮助到大家。 1.断点调试是啥?难不难? 断点调试其实并不是多么复杂的一件事,简单的理解无外呼就是打开浏览器,打开sources找到js文件,在行号上点一下罢了。操作起来…

    2025年3月8日 编程技术
    200
  • js中正则知识总结

    本文主要和大家分享js中正则知识总结,主要以代码的方法和大家讲解,希望能帮助到大家。 方法: 1、 testvar string=”abvfddsadew”;var reg=/ D/;reg.test(string) //记住test是正则…

    编程技术 2025年3月8日
    200
  • js回调详解

    本文主要和大家介绍js回调详解,在用js时候,刚接触了个回调,差点把自己饶进去,好再出来了,现在屡屡思路。 先来个简单的代码: var rows = [{name:”123″},{name:”456″}];var each = functi…

    编程技术 2025年3月8日
    200

发表回复

登录后才能评论