首页 > 其他分享 >精通正则表达式- 引擎

精通正则表达式- 引擎

时间:2022-12-05 17:36:44浏览次数:34  
标签:精通 匹配 NFA 正则表达式 matches 引擎 DFA 表达式

1. 引擎的类型

  • 传统型NFA
  • POSIX NFA
  • DFA (不支持忽略优先量词,捕获组和回朔)

Javascript测试代码:

  1. 首先测试是否是传统型NFA
/** 如果匹配结果是nfa则为传统型NFA **/
const reg = /nfa|nfa not/;
const matches = reg.exec('nfa not');
console.log(matches[0]); // nfa
  1. 再测试是否是DFA引擎,否则为POSIX NFA
/** 如果匹配时间很短则为DFA,如果匹配时间很长或者程序崩溃则为POSIX NFA **/
const reg = /X(.+)+X/;
const matches = reg.exec('=XXX===============================');
console.log(matches[0]);

2. 一般匹配原则

  • 优先选择最左端的匹配结果
/** 匹配结果为belly **/ 
const reg = /fat|cat|belly|your/;
const matches = reg.exec('The dragging belly indicates that your cat is too fat.');
console.log(matches[0]); // belly

分析:在正则表达式的多选结构所有的选项都可以匹配到下面的字符串,但是belly 是在字符串的最左端
首先得到匹配的。

  • 标准的匹配量词(* + ? {m,n}) 是匹配优先的
    简而言之,标准匹配量词的结果可能并非所有可能中最长的,但它们总是尝试匹配尽可能多的字符,直到
    匹配上限为止。
const reg = /\b\w+s\b/;
const matches  = reg.exec('regexes');
console.log(matches[0]);

分析:\w+ 完全能够匹配整个单词,但如果\w+来匹配整个单词,s就无法匹配了,
为了完成匹配,\w+必须匹配regexe,把最后的s留出来。

3. 匹配原理

  • NFA引擎(表达式主导)
    正则表达式从头开始,每次检查一部分(由引擎查看表达式的一部分),同时检查“当前文本”是否匹配表达式
    的当前部分。如果是,则继续表达式的下一部分,如此继续,直到表达式的所有部分都能匹配,即整个表达式
    能够匹配成功。简而言之就是以文本来匹配占主导权的正则表达式。

/to(nite|knight|night)/.exec('tonight')

在上面的正则表达式例子中,第一个元素是t,它将会重复尝试,直到在目标字符串中找到't'为止。之后,
就检查紧随其后的字符是否是由o匹配,如果能,就检查下面的元素。下面的元素指(nite|knight|night)
它的真正含义是"nite 或者knight或者night"。引擎会依次尝试这3种可能。我们能够发现,如果匹配的字符串
是tonight,第三个选择能够匹配。但表达式主导的引擎必须完全测试,才能得出结论。

尝试nite的过程与之前一样:“尝试匹配n,然后是i,然后是t,最后是e。”如果这种尝试失败,引擎会选择另
一种可能,如此继续下去,直到匹配成功或是失败。表达式中的控制权在不同元素之间转换,所以称它为”表达
式主导“。
  • DFA引擎(文本主导)
    DFA引擎在扫描字符串时,会记录“当前有效”的所有匹配可能。我们称之为“文本主导”,是因为它扫描的字符串
    中的每个字符都对引擎进行了控制。简而言之就是用正则表达式来匹配主导权的文本。

最左最长规则(DFA 以及POSIX NFA会遵守最左最长规则)

const reg = /one(self)?(selfsufficient)?/;
const matches = reg.exec('oneselfsufficient');
console.log(matches[0]);

传统型NFA:NFA首先会匹配one, 然后是匹配(self)? 留下(selfsufficient)? 来匹配sufficient。它显然
无法匹配,但整个表达式并不会因此匹配失败,因为这个元素不是必须匹配的。所有传统型NFA会返回oneself,
放弃没有尝试的状态。

DFA引擎:DFA会返回更长的结果oneselfsufficient, DFA会同时记录多个匹配,在其中选择最左最长的匹配作为
最终结果。

POSIX NFA: 传统型NFA引擎会在第一次找到匹配时停一下来,但是POSIX NFA则会继续尝试其他分支,穷经
所有的分支,然后从中选择最长的匹配结果。

4. NFA 与 DFA 的比较

  • 在预编译阶段
    在使用正则表达式搜索之前,两种引擎都会编译表达式,得到一套内化形式,适应各自的匹配算法。NFA的
    编译过程通常要快一些,需要的内存也更少一些。

  • 匹配速度
    正常情况下,两种引擎的匹配速度差不多,一般来说,DFA的速度与正则表达式无关,而NFA则两者直接相关。

    传统的NFA在报告无法匹配以前,必须尝试正则表达式的所有变体。传统型NFA如果能找到一个匹配,肯定会
    停止匹配。

    POSIX NFA 必须尝试正则表达式的所有变体,确保获得最长的匹配文本,所以如果匹配失败,它所花的时间与传统型NFA一样(有可能更长)。所以POSIX NFA,表达式的效率问题更为重要。

    DFA不需要做太多的优化,因为它匹配的速度很快。

  • 匹配结果
    DFA(或者POSIX NFA)返回最左边最长的匹配文本。传统型NFA可能返回同样的结果,也可能返回别的文本,
    因为传统型NFA会在匹配成功时停止匹配,因此不一定得到最长的匹配结果。

  • 匹配能力
    NFA引擎能提供一些DFA不支持的功能。

    1. 捕获组: 捕获由括号内子表达式匹配的文本。
    2. 环视: 匹配符合条件的某个位置。
    3. 忽略优先量词: 非匹配优先,能够匹配尽量少的内容。
    4. 有序的多选结构: 在多选结构中从左到右依次匹配,不是选择最长的匹配,也不是选择最短的匹配。
    5. 占有优先量词: 子表达式一旦匹配成功,不会再交还已经匹配的内容。
    6. 固化分组: 与占有优先量词的功能相同。

标签:精通,匹配,NFA,正则表达式,matches,引擎,DFA,表达式
From: https://www.cnblogs.com/xiaodi-js/p/16952930.html

相关文章

  • 正则表达式
    正则表达式:按照某种规则去匹配符合条件的字符串      基本匹配,可以在这里练习正则表达式https://regex101.com/   元字符   点运算符 -->......
  • 正则表达式全集
    摘自:https://tool.oschina.net/uploads/apidocs/jquery/regexp.html表达式全集字符描述\将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个......
  • 火山引擎DataTester:一个爆款游戏产品,是如何用A/B测试打磨出来的?
    更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群随着国内游戏用户数量趋于饱和,中国游戏产业也从高速成长期逐渐转型,市场成熟度提升,竞争......
  • 火山引擎DataTester:一个爆款游戏产品,是如何用A/B测试打磨出来的?
    随着国内游戏用户数量趋于饱和,中国游戏产业也从高速成长期逐渐转型,市场成熟度提升,竞争趋于精细化。随着游戏出海以及私域流量运营的挑战,游戏企业对数据分析的使用需求和依......
  • CentOS7.0下完美部署Solr 搜索引擎
    一、环境准备:系统环境:CentOS-7.0.1406       tomcat-7.0.29       jdk-7u9       solr-4.7.0首先将软件包上传到/tmp目录下1、 jdk安装[ro......
  • 03#JS 工具函数:正则表达式匹配字符,替换该字符,支持多个正则表达式替换
    /***替换字符串,默认替换""。传递regExps,一个正则表达式数组。**@paramsource被修剪的字符串*@paramregExps正则表达式,找到匹配的字符串,然后替换掉*@pa......
  • MySQL存储引擎
    1.MyISAM底层存储(非聚集索引方式)与InnoDB底层存储(聚集索引方式)1.1MyISAM底层存储(非聚集索引方式)Myisam创建表后生成的文件有三个:frm:创建表的语句MYD:表里面的数据文......
  • JDK中内嵌JS引擎介绍及使用
    原文:JDK中内嵌JS引擎介绍及使用-Stars-One的杂货小窝最近研究阅读这个APP,其主要功能就是通过一个个书源,从而实现移动端阅读的体验比如说某些在线小说阅读网站,会加......
  • 10 虚拟机字节码执行引擎_方法调用
    目录1关于方法调用2方法解析3方法分派3.1静态分派3.1.1静态分派概述3.1.2方法重载分析3.1.3静态类型和动态类型3.2动态分派3.2.1invokevirtual指令详解3.2.2动态......
  • MySQL存储引擎
    一、mysql存储引擎概述1.1存储引擎MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种技术都使用不同的存储机制、索引技巧、锁定水平并且最终提......