返回顶部
首页 > 资讯 > 前端开发 > html >正则表达式的原理介绍
  • 482
分享到

正则表达式的原理介绍

2024-04-02 19:04:59 482人浏览 薄情痞子
摘要

本篇内容主要讲解“正则表达式的原理介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“正则表达式的原理介绍”吧!正则表达式可能大部分人都用过,但是大家在使用的时候

本篇内容主要讲解“正则表达式的原理介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“正则表达式的原理介绍”吧!

正则表达式可能大部分人都用过,但是大家在使用的时候,有没有想过正则表达式背后的原理,又或者当我告诉你正则表达式可能存在性能问题导致线上挂掉,你会不会觉得特别吃惊?

我们先来看看7月初,因为一个正则表达式,导致线上事故的例子。

https://blog.cloudflare.com/d...

简单来说就是一个有性能问题的正则表达式,引起了灾难性回溯,导致cpu满载。

性能问题的正则

先看看出问题的正则

正则表达式的原理介绍

引起性能问题的关键部分是 .*(?:.*=.*) ,这里我们先不管那个非捕获组,将性能问题的正则看做 .*.*=.* 。

其中 . 表示匹配除了换行以外的任意字符(很多人把这里搞错,容易出bug), .* 表示贪婪匹配任意字符任意次。

什么是回溯

在使用贪婪匹配或者惰性匹配或者或匹配进入到匹配路径选择的时候,遇到失败的匹配路径,尝试走另外一个匹配路径的这种行为,称作回溯。

正则表达式的原理介绍

可以理解为走迷宫,一条路走到底,发现无路可走就回到上一个三岔口选择另外的路。

回溯现象

// 性能问题正则  // 将下面代码粘贴到浏览器控制台运行试试  const regexp = `[A-Z]+\\d+(.*):(.*)+[A-Z]+\\d+`;  const str = `A1:B$1,C$1:D$1,E$1:F$1,G$1:H$1`  const reg = new RegExp(regexp);  start = Date.now();  const res = reg.test(str);  end = Date.now();  console.log('常规正则执行耗时:' + (end - start))

现在来看看回溯究竟是怎么一回事

假设我们有一段正则 (.*)+\d ,这个时候输入字符串为 abcd ,注意这个时候仅仅输入了一个长度为4的字符串,我们来分析一下匹配回溯的过程:

正则表达式的原理介绍

上面展示了一个回溯的匹配过程,大概描述一下前三轮匹配。

注意 (.*)+ 这里可以先暂且看成多次执行 .* 。 (.*){1,}

正则表达式的原理介绍

***次匹配,因为 .* 可以匹配任意个字符任意次,那么这里可以选择匹配空、a、ab、abc、abcd,因为 * 的贪婪特性,所以 .* 直接匹配了 abcd 4个字符, + 因为后面没有其他字符了,所以只看着 .* 吃掉 abcd 后就不匹配了,这里记录 + 的值为1,然后 \d 没有东西能够匹配,所以匹配失败,进行***次回溯。

正则表达式的原理介绍

第二次匹配,因为进行了回溯,所以回到上一个匹配路径选择的时候,上次 .* 匹配的是 abcd ,并且路不通,那么这次只能尝试匹配 abc ,这个时候末尾还有一个 d ,那么可以理解为 .* ***次匹配了 abc ,然后因为 (.*)+ 的原因, .* 可以进行第二次匹配,这里 .* 可以匹配 d ,这里记录 + 的值为2,然后 \d 没有东西能够匹配,所以匹配失败,进行第二次回溯。

正则表达式的原理介绍

第三次匹配,因为进行了回溯,所以回到上一个匹配路径选择的时候,上次***个 .* 匹配的是 abc ,第二个 .* 匹配的是 d ,并且路不通,所以这里第二次的 .* 不进行匹配,这个时候末尾还有一个 d , \d 和 d 匹配失败,进行第三次回溯。

如何减少或避免回溯

  •  优化正则表达式:时刻注意回溯造成的性能影响。

  •  使用DFA正则引擎的正则表达式

什么是DFA正则引擎

传统正则引擎分为NFA(非确定性有限状态自动机),和DFA(确定性有限状态自动机)。

DFA

对于给定的任意一个状态和输入字符,DFA只会转移到一个确定的状态。并且DFA不允许出现没有输入字符的状态转移。

正则表达式的原理介绍

比如状态0,在输入字符A的时候,终点只有1个,只能到状态1。

NFA

对于任意一个状态和输入字符,NFA所能转移的状态是一个非空集合。

正则表达式的原理介绍

比如状态0,在输入字符A的时候,终点可以是多个,即能到状态1,也能到状态0。

DFA和NFA的正则引擎的区别

那么讲了这么多之后,DFA和NFA正则引擎究竟有什么区别呢?或者说DFA和NFA是如何实现正则引擎的呢?

DFA

正则里面的DFA引擎实际上就是把正则表达式转换成一个图的邻接表,然后通过跳表的形式判断一个字符串是否匹配该正则。

// 大概模拟一下  functioMachine(input) {      if (typeof input !== 'string') {          console.log('输入有误');          return;      }      // 比如正则:/abc/ 转换成DFA之后      // 这里我们定义了4种状态,分别是0,1,2,3,初始状态为0      const reg = {          0: {              a: 1,          },          1: {              b: 3,          },          2: {              isEnd: true,          },          3: {              c: 2,          },      };      let status = 0;      for (let i = 0; i < input.length; i++) {          const inputinputChar = input[i];          status = reg[status][inputChar];          if (typeof status === 'undefined') {              console.log('匹配失败');              return false;          }      }      const end = reg[status];      if (end && end.isEnd === true) {          console.log('匹配成功');          return true;      } else {          console.log('匹配失败');          return false;      }  }  const input = 'abc';  machine(input);

优点:不管正则表达式写的再烂,匹配速度都很快

缺点:高级功能比如捕获组和断言都不支持

NFA

正则里面NFA引擎实际上就是在语法解析的时候,构造出的一个有向图。然后通过深搜的方式,去一条路径一条路径的递归尝试。

正则表达式的原理介绍

优点:功能强大,可以拿到匹配的上下文信息,支持各种断言捕获组环视之类的功能

缺点:对开发正则功底要求较高,需要注意回溯造成的性能问题

总结

现在回到问题的开头,我们再来看看为什么他的正则会有性能问题

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区

  2.  首先他的正则使用的NFA的正则引擎(大部分语言的正则引擎都是NFA的,js也是,所以要注意性能问题产生的影响)

  3.  他写出了有性能问题的正则表达式,容易造成灾难性回溯。

如果要避免此类的问题,要么提高开发对正则的性能问题的意识,要么改用DFA的正则引擎(速度快,功能弱,没有补货组断言等功能)。

注意事项

在平常写正则的时候,少写模糊匹配,越精确越好,模糊匹配、贪婪匹配、惰性匹配都会带来回溯问题,选一个影响尽可能小的方式就好。写正则的时候有一个性能问题的概念在脑子里就行。

到此,相信大家对“正则表达式的原理介绍”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

--结束END--

本文标题: 正则表达式的原理介绍

本文链接: https://lsjlt.com/news/80610.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 正则表达式的原理介绍
    本篇内容主要讲解“正则表达式的原理介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“正则表达式的原理介绍”吧!正则表达式可能大部分人都用过,但是大家在使用的时候...
    99+
    2024-04-02
  • grep中的正则表达式介绍
    本篇内容介绍了“grep中的正则表达式介绍”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!grep是Linux中用于处理文件的工具之一。gre...
    99+
    2023-06-05
  • 正则表达式语法详细介绍
    这篇文章主要介绍“正则表达式语法详细介绍”,在日常操作中,相信很多人在正则表达式语法详细介绍问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”正则表达式语法详细介绍”的疑惑有所帮助!接下来,请跟着小编一起来学习吧...
    99+
    2023-06-02
  • VBS正则表达式简介
    本篇内容介绍了“VBS正则表达式简介”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!正则表达式如果原来没有使用过正则表达式,那么可能对这个术语...
    99+
    2023-06-09
  • PHP正则表达式修饰符的简单介绍
    本篇内容介绍了“PHP正则表达式修饰符的简单介绍”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!我们在PHP正则表达式的学习中会碰到修饰符,那...
    99+
    2023-06-17
  • 匹配中文汉字的正则表达式介绍
    正则表达式是一种用来描述、匹配和操作文本的工具,它可以用来检索、替换和验证字符串。要匹配中文汉字,可以使用Unicode编码范围来定...
    99+
    2023-08-15
    正则表达式
  • VBS正则表达式中普通字符的介绍
    本篇内容主要讲解“VBS正则表达式中普通字符的介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“VBS正则表达式中普通字符的介绍”吧!普通字符普通字符由所有那些未显式指定为元字符的打印和非打印字...
    99+
    2023-06-09
  • Python正则表达式基本原理
    目录⭐️正则表达式  正则表达式是什么?🌟1.实例引入🌟2.match()✨匹配目标✨贪婪匹配🌟3.findall()🌟常用符号🌟特殊字符🌟总结⭐️正则表达式&n...
    99+
    2023-05-15
    Python正则表达式原理 Python正则表达式
  • VBS正则表达式后向引用的详细介绍
    本篇内容介绍了“VBS正则表达式后向引用的详细介绍”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!后向引用正则表达式一个最重要的特性就是将匹配...
    99+
    2023-06-09
  • Python字符串与正则表达式详细介绍
    目录一、字符串相关操作 二、正则表达式相关操作一、字符串相关操作  1.统计所输入字符串中单词的个数,单词之间用空格分隔。其运行效果如下图所示。 s=input(...
    99+
    2024-04-02
  • 正则表达式
    2019-01-16 作用 :     路由匹配,表单信息的验证  (字符串匹配) 信息提取(在大段文本中提取信息,爬虫) 字符串的提取和校验 []在中括号内匹配任意项  [^]不匹配中括号中的任意一项    [0-9]  0123......
    99+
    2023-01-30
    正则表达式
  • 理解python正则表达式
    在python中,对正则表达式的支持是通过re模块来支持的。使用re的步骤是先把表达式字符串编译成pattern实例,然后在使用pattern去匹配文本获取结果。 其实也有另外一种方式,就是直接使用re模块...
    99+
    2022-06-04
    正则表达式 python
  • Python正则表达式的基本原理是什么
    这篇文章主要讲解了“Python正则表达式的基本原理是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python正则表达式的基本原理是什么”吧!正则表达式是什么?正则表达式,又称规则表达...
    99+
    2023-07-06
  • ORACLE 正则表达式
    ORACLE中的支持正则表达式的函数主要有下面四个:1,REGEXP_LIKE :与LIKE的功能相似2,REGEXP_INSTR :与INSTR的功能相似3,REGEXP_SUBSTR :与SUBSTR的...
    99+
    2024-04-02
  • shell正则表达式
         Shell脚本扩展一 正确表达式正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。1. 支持的命令:grep、vim、fi...
    99+
    2024-04-02
  • PHP正则表达式
    什么是正则表达式? 正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文 正则表达...
    99+
    2023-09-02
    正则表达式 php 前端
  • java正则表达式
    目录 一、概念 二、正则表达式语法 三、捕获组 四、Pattern类与Matcher类 1.matches( ) 2.split( ) 3.find( ) 4.group 5.start( )和end( ) 6.replace替换 7.re...
    99+
    2023-09-21
    java 正则表达式
  • qt 正则表达式
      以上是正则表达式的格式说明 以下是自己写的正则表达式  22-25行 是一种设置正则表达式的方式, 29-34行 : 29行 new一个正则表达式的过滤器对象 30行 正则表达式 的过滤格式 这个格式是0-321的任意数字都可以输入...
    99+
    2023-09-12
    qt
  • Linux:正则表达式
    目录 一、grep和元字符         1.1、grep         1.2、元字符 二、正则匹配          2.1、查找特定的字符          2.2、使用[]来查找集合字符         要查找short和shi...
    99+
    2023-09-08
    正则表达式 java shell linux 服务器
  • Python_正则表达式
    正则表达式: 匹配字符串   re.compile():用于编译正则表达式,生成一个正则表达式对象,供 match() 和 search() 两个函数使用,一般建议使用这种编译方式 1 import re 2 str = 'abc1de...
    99+
    2023-01-30
    正则表达式
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作