一种支持复杂字符集的NFA高效构造方法

简介: 背景当前正则表达式NFA(非确定有穷自动机,Non-deterministic finite automaton)构造方法,通常需要先借助“堆栈(Stack)”构造“语法树(SyntaxTree)”,然后,将语法树转换为NFA。由于正则语义的嵌套层级未知,导致堆栈的大小不可控,容易导致内存溢出错误,并且,构造语法树也需要一定的消耗CPU。同时,传统的NFA在复杂字符集的情况下,采用邻接矩阵(全量数

背景

当前正则表达式NFA(非确定有穷自动机,Non-deterministic finite automaton)构造方法,通常需要先借助“堆栈(Stack)”构造“语法树(SyntaxTree)”,然后,将语法树转换为NFA。由于正则语义的嵌套层级未知,导致堆栈的大小不可控,容易导致内存溢出错误,并且,构造语法树也需要一定的消耗CPU。同时,传统的NFA在复杂字符集的情况下,采用邻接矩阵(全量数组)或邻接表的方式存储状态跳转,存在空间存储较大或者匹配性能较差的问题。

本文,消除构造“语法树(SyntaxTree)”环节,采用有序邻接区间表的存储方式,实现了一种无需申请额外的“堆栈(Stack)”空间且存储空间压缩率较高的正则表达式NFA高效构造方法。

怎么实现的?

本文提出一种支持复杂字符集的NFA高效构造方法,无需开辟额外的“堆栈(Stack)”空间,进而避免出现内存溢出错误,无需创建“语法树(SyntaxTree)”,进而加快了构造速度,采用有序邻接区间表,较好的实现了复杂字符集功能。系统模块设计分为三部分:正则预处理、NFA构造。

   A)正则预处理,用于判定是否需要在头部增加“前缀.*”。

正则匹配模式包含两种:搜索和匹配。“搜索”表示字符串是否包含符合正则表达式的子串,“匹配”表示整个字符串是否符合正则表达式。

如果正则匹配为“搜索”模式,并且正则第一个字符不是“^”(字符^用于限定开头),则需要为此正则表达式增加“前缀.*”。例如:搜索模式的正则表达式“abc”,在头部增加“前缀.*”得到的正则表达式为“.*abc”。

   B)NFA构造。遍历正则表达式,同步构造NFA,无需创建“语法树(SyntaxTree)”。

1.创建“当前自动机nowNfa”。

2.遍历正则表达式,根据“当前字符currentCharacter”所属的字符类型(字符转换、量词、或、小括号),分别执行对应操作。

(1)字符转换

如果“当前字符currentCharacter”为“转义字符”,则解析“转义字符”、“16进制”、“8进制”得到“结果字符集resultCharSet”。

如果“当前字符currentCharacter”为“非元字符”,则解析为只包含“非元字符”的“结果字符集resultCharSet”。

如果“当前字符currentCharacter”为“任意字符.”,则解析为包含“所有字符”的“结果字符集resultCharSet”。

如果“当前字符currentCharacter”为“区间值[]”,则解析为包含“所有区间值”的“结果字符集resultCharSet”。

默认情况,解析为只包含“一个字符”的“结果字符集resultCharSet”。

如果“下一个字符nextChar”为“量词”,则将当前结果转化为“下一个自动机nextNfa”。否则,为“当前自动机nowNfa”根据“结果字符集resultCharSet”添加跳转操作。

如果“结果字符集resultCharSet”包含了汉语,例如:“.*中国.*”、“ [\u4e00-\u9fa5]”、[^abc],此时跳转表仅采用包含256个元素的数组不能表达上述语义,需要在后面采用“有序区间邻接表”表示超出常见字符集的复杂字符集部分。小于256的常见字符集通过数组索引能够直接定位,超过255的部分需要采用二分查找模式判定匹配结果。

(2)量词

如果“当前字符currentCharacter”为“*”,则解析值为“{0,+∞}”的“量词区间countInterval”。

如果“当前字符currentCharacter”为“?”,则解析值为“{0,1}”的“量词区间countInterval”。

如果“当前字符currentCharacter”为“+”,则解析值为“{1,+∞}”的“量词区间countInterval”。

如果“当前字符currentCharacter”为“{”,则解析值为“{m,n}”的“量词区间countInterval”。

量词复制操作repeat会造成状态膨胀,比如形如{10000}的量词会repeat10000次,由此也会创建10000个NFA状态,这种情形极易造成内存超限。为此本文在量词操作repeat前做了次数阈值限定,如果repeat次数超过阈值(比如:10),则转换为量词节点自转换操作nodeSelfConvert,此操作采用“标记位Tag”和“计数器Counter”的方式表示此量词。在匹配过程中遇到此类型的“标记位Tag”,需要比较当前“计数器Counter”是否符合量词限定,如果符合则继续执行匹配操作,同时将当前“计数器Counter”加1。

首先,判断根据量词是否超过阈值,然后,确定针对“下一个自动机nextNfa”执行量词复制操作repeat还是量词节点自转换操作nodeSelfConvert,最后,针对“当前自动机nowNfa”和“下一个自动机nextNfa”执行连接操作connact。

(3)或

如果“当前字符currentCharacter”为“|”,则针对“后续的正则表达式子串”构造“单独的自动机newNfa”。

针对“当前自动机nowNfa”和“单独的自动机newNfa”执行或操作or。

(4)小括号

如果“当前字符currentCharacter”为“(”,则针对 “处于小括号内正则表达式子串”构造“单独的自动机newNfa”。

针对“当前自动机nowNfa”和“单独的自动机newNfa”执行连接操作connact。

    支持复杂字符集的NFA高效构造算法执行参照:

                    

                                                                                                                                                                     

有哪些实际价值?

1)构造时间短:遍历正则表达式的同时,直接构造了NFA,无需中间结果“语法树(SyntaxTree)”,效率较高,程序具体较短的执行时间。                                             

2)内存可控:程序执行过程中无需额外申请与“正则串长度成正比”的“堆栈(Stack)”内存空间,避免内存溢出风险,保障程序正常运行。

3)匹配效率高:高频使用的前256个字符采用数组方式存储可以直接定位,其他复杂字符集采用有序邻接区间表采用二分查找定位,上述两种类型的匹配效率均较高。

相关文章
|
10月前
|
SQL 存储 关系型数据库
MySQL主从复制 —— 作用、原理、数据一致性,异步复制、半同步复制、组复制
MySQL主从复制 作用、原理—主库线程、I/O线程、SQL线程;主从同步要求,主从延迟原因及解决方案;数据一致性,异步复制、半同步复制、组复制
985 11
|
安全 JavaScript
如何在`package.json`中正确设置依赖版本范围?
正确设置 `package.json` 中的依赖版本范围需要综合考虑项目的需求、依赖库的稳定性和兼容性,以及开发和维护的便利性等因素。通过合理选择版本范围符号,并结合定期的审查和测试,可以有效地管理项目依赖,确保项目的稳定运行。
421 1
|
机器学习/深度学习 数据采集 传感器
使用Python实现深度学习模型:智能极端天气事件预测
使用Python实现深度学习模型:智能极端天气事件预测
979 3
|
安全 C++
超级好用的C++实用库之环形内存池
超级好用的C++实用库之环形内存池
323 5
|
数据采集 存储 人工智能
cdga|数据治理:应对核心业务数据质量参差不齐的挑战与策略
数据治理是指通过制定并实施一系列政策、流程和技术手段,确保数据的可用性、完整性、准确性和安全性,以支持企业的决策和业务运营。对于核心业务数据质量参差不齐的问题,数据治理的重要性不言而喻
|
存储 缓存 安全
在Linux中,什么是软件仓库,并且如何管理它?
在Linux中,什么是软件仓库,并且如何管理它?
|
JavaScript 算法 前端开发
基于抽象语法树+diff算法实现Markdown编译器
基于抽象语法树+diff算法实现Markdown编译器
|
Web App开发 安全 API
WebRTC 技术在实时通信中的应用与实现
WebRTC(Web Real-Time Communication)是一种支持实时音视频通信的开放式标准。它允许在 Web 浏览器之间进行点对点的音视频通信,而无需安装插件或其他额外的软件。WebRTC 在实时通信领域有着广泛的应用,包括视频通话、音频通话、实时消息等。下面将介绍 WebRTC 技术在实时通信中的应用与实现。
571 0
|
前端开发 NoSQL Java
基于Springboot+Vue实现前后端分离商城管理系统
基于Springboot+Vue实现前后端分离商城管理系统
747 1
|
Java 关系型数据库 MySQL
windows部署DataX及运行dataX_WEB
windows部署DataX及运行dataX_WEB
4517 0
windows部署DataX及运行dataX_WEB