2019独角兽企业重金招聘Python工程师标准>>>

大概和我不以程序员为职业有关吧,我本人是比较喜欢算法的那种,当然是比不了科班出身的。

比如我就写过很多版本的算术表达式解析器,优先级堆栈的;二叉树的;分治策略的;修正计算顺序的……

正则表达式两个我也写过两个,一个采用的回溯算法,另一个则是二叉树版本的,虽然这俩倒是都能用吧,但是对分组的处理(分组是采用递归调用的方法实现的,相当于另一个正则表达式)实在是不太好,这个缺点导致很多时候搜索的结果会遗漏很多,而二叉树版本的还有个缺点是选择操作“|”只能获得第一个匹配…………

就效果看,这俩都是残次品。

后来,我在vczh的博客里看到了他的一个科普贴子,在那里面,我才了解到还有有限自动机这种方法。

之后我花了不少时间去思考,因为总觉得这个方法太麻烦了,断断续续有2-3个月吧,想来想去也没想出什么更好的法子,最后还是觉得只有用有限自动机才合适。

不过多少我还是做了些修改的,倒不是为了效率,是为了减少打字量……

主要修改如下:

(1)不每个字符转移一次状态,而是尽可能的把连续的字符作为一个整体进行比对。

(2)不弄什么字母分组表,数据结构就使用指针链表,节省工作量

(3)“{a,b}”这种有次数限定的重复,vczh是采用复制节点实现的,我采用增加状态边来解决(效率会下降)

(4)分组命名,向前向后预查这些花哨而实用的功能,俺就丢了

那么,整体上看,正则表达式引擎的设计我就划分为如下几个步骤:

1)对规则字符串做预处理,主要是换行这类要使用转义符的字符,这个预处理可以把这些字符还原

2)将规则字符串进行划分,修正成操作符、操作数的列表形式

3)对这个列表进行处理,获得NFA状态转移图

4)将NFA状态转移图里的ε边消去,减少状态转移数

5)利用得到的状态转移图,对字符串进行匹配

第一步很容易解决,无非就是找到'\',然后将后跟't'、'n'、'r'等字符的修正为相应的制表、换行……

第二步也相对简单,无非是识别几个操作符:

'*'、'+'、'?'、'*?'、'+?'、'??'、'('、'(:'、')'、'|'、'['、']'、'{'、'}'

比较特殊的是:

因为把连续的字符看做一个整体,所以在后跟重复或者可选运算符时,要检查一下是否需要断开字符串;

'['后面要一直读取到前面不是'\'的']',期间不作分析,结果作为一个整体

'{'后面有'{a}'、'{a,}'、'{,a}'、'{a,b}'这几种形式,同样是读取为一个整体

还有一个隐藏的操作符,它的作用是将两个操作数连接起来,类似算术里的“*”,关于它另有介绍[*]

如此一来,列表里的成员记录的内容就会有好几种,python里这不算啥,C++里就麻烦一些,我采用的是struct和union来回嵌套+标志字节的办法来处理这个问题。

(如果使用正则表达式这一步非常轻松,可是如果用了就真成了笑话了)

第三步见下一帖

[*]被隐藏了的“连接”运算符,比如“ab[cd]”这个字符串,分析后的两个元素“ab”和“[cd]”正是通过这个操作符连接的。这个隐藏运算符我是用后面的Operator类的一个补足函数来填充修复的,不然就得另外写一个函数了。

转载于:https://my.oschina.net/liudiwu/blog/111327

从头开始,搭建一个正则表达式引擎(一)整体构架、预处理相关推荐

  1. 从头开始搭建一个dubbo+zookeeper平台

    2019独角兽企业重金招聘Python工程师标准>>> 本篇主要是来分享从头开始搭建一个dubbo+zookeeper平台的过程,其中会简要介绍下dubbo服务的作用. 首先,看下一 ...

  2. 实现一个正则表达式引擎in Python(一)

    前言 项目地址:Regex in Python 开学摸鱼了几个礼拜,最近几天用Python造了一个正则表达式引擎的轮子,在这里记录分享一下. 实现目标 实现了所有基本语法 st = 'AS342abc ...

  3. 如何使用Julius搭建一个语音识别引擎?

    使用Julius搭建一个语音识别引擎这里主要就是听写程序,可以进行一段语音的连续识别,而且主要是针对中文: 一.语音识别引擎的基本结构 基本所有的开源语音识别引擎都是如下的结构,包括:Sphinx,J ...

  4. 实现一个正则表达式引擎in Python(三)

    项目地址:Regex in Python 前两篇已经完成的写了一个基于NFA的正则表达式引擎了,下面要做的就是更近一步,把NFA转换为DFA,并对DFA最小化 DFA的定义 对于NFA转换为DFA的算 ...

  5. 实现一个正则表达式引擎in Python(二)

    项目地址:Regex in Python 在看一下之前正则的语法的 BNF 范式 group ::= ("(" expr ")")* expr ::= fact ...

  6. 在企业内部, 从头开始搭建一个云原生的 “企业内部报销系统”, 需要哪些步骤?

    2021年云原生技术比较火爆,作为一个关注技术热点的IT从业者,出现新的技术热点后必须关注一下.不理解的就先百度一下,百度是这样解释云原生的: 云原生是基于分布部署和统一运管的分布式云 ,以容器.微服 ...

  7. 从头开始搭建一个mybatis+postgresql平台

    最近有个项目的数据库使用postgresql,使用原生态的mybatis操作数据,原生态的没什么不好,只不过国内有个tk.mybatis的工具帮助我们做了很多实用的事情,大多数情况下我们需要在原生态m ...

  8. 手把手搭建一个redis集群

    文章目录 前言 安装的含义 安装redis redis编译安装 redis集群 redis集群的使用 C++工程连接使用redis-cluster hiredis-cluster 总结 前言 所谓&q ...

  9. 正则表达式引擎 源码 c#_如何在C#中构建正则表达式引擎

    正则表达式引擎 源码 c# 更新: (Update:) See my Unicode enabled offering here 在这里查看启用Unicode的产品 先决条件 (Prerequisit ...

最新文章

  1. matlab读入txt数据_教程合集 | MATLAB文件读写(以nc与txt为例)
  2. nand ubi -4 kernel和mtd
  3. pydebugger
  4. 检查虚ip跟实ip之间网络问题_虚电路有哪些特点 虚电路原理介绍【详解】
  5. 架构可视化支撑系统演进探索
  6. WPF DataGrid 对行中单元格的访问
  7. python中如何判断一个变量的数据类型?(原创)
  8. 图片怎样压缩到100KB以下?怎样压缩图片小于100KB?
  9. 【数字图像处理matlab】sobel、prewitt算子图像锐化
  10. session 与 coolie 的区别与联系
  11. []趋势科技2015校园招聘
  12. 最值得看的电影,一生必看的50部电影,您看过几部影
  13. 5G C-V2X技术介绍
  14. 读书笔记之《好好说话》
  15. 图片还原去遮挡_如何把人像照片上的遮盖物去除看到原来人像?
  16. HiveSql计算占比、同比、占环比
  17. ug支持linux系统吗,UG12.02-linux,感兴趣的可以下载
  18. 数仓--拉链表实战⭐⭐⭐⭐⭐
  19. 仿QQ点赞吹泡泡效果
  20. 果快服务器维护中 稍后再试,维护中什么意思?服务维护中是什么意思

热门文章

  1. KMM Kotlin expect的几种声明方式
  2. 数据结构特性解析 (二) ArrayList
  3. 微信小程序-WXML转换类型
  4. 微信小程序开发之scroll-view上拉加载数据实现
  5. 2021-05-08 docker  拷贝东西到镜像,和拷贝到宿主机
  6. Eddy的难题_JAVA
  7. 【多线程】0.理解一下5种IO模型、阻塞IO和非阻塞IO、同步IO和异步IO
  8. Programming Computer Vision with Python (学习笔记八)
  9. IntelliJ IDEA 常用设置
  10. Spring AOP 源码分析 - 筛选合适的通知器