正则表达式引擎实现体会
来源:互联网 发布:cv source数据库 复旦 编辑:程序博客网 时间:2024/06/07 00:20
学编译原理的词法分析部分,看到了正则表达式,于是就动手自己实现了一番。
代码:https://github.com/earayu/Regex.git
正则表达式的解析:
正则表达式->NFA->DFA->模拟DFA运行的形式
除了这种方式以外,还能直接模拟NFA,虚拟机等方法,但还是DFA形式最接近编译原理。
一开始的时候并不知道如何下手,龙书中只是提供了几个算法(子集构造法等)和NFA、DFA的定义。并没有“手把手”地教如何实现正则表达式解析引擎。
我先是构建了NFA的数据结构—-有向图。DFA类似,然后实现了子集构造法。这样就可以把NFA转成DFA了,然后实现了DFA的模拟。但完全不知道如何从(带括号的)正则表达式转换为NFA。龙书中只是给了3个基本操作的转换,并没有太大帮助。后来才发现可以将正则表达式转换成后缀式,然后用双栈来构造NFA,这是关键的一步。
做完以上工作,终于可以完成 . | *3个操作了(以及括号功能)。这时候,我们再加入转义功能以及一些语法糖。
比如:[a-zA-Z0-9] + ? {m,n} \s \w 等
再深入的话就是加入一些高级功能:
(?=XXX) (?<=XXX) 等
这样DFA就不够用了,需要NFA。
关于正则引擎,需要2种功能:match和search。
match是先有一个正则表达式,如(a|b)*ccd。再用某个字符串去匹配。这个例子中 “abbaabaccd”匹配成功, “abbccc”匹配失败。这个实现很简单。
search就是查找,在字符串txt中寻找跟正则表达式匹配的子字符串,返回索引值。我不知道正轨套路是什么样的,但我根据KMP算法的思想,自己写了一个search方法。时间复杂度也是O(N)的,所以还算可以。
差不多写好了正则引擎,对长表达式测试了一下,发现构造DFA很慢。4000个字符的表达式花费了69秒,这显然是无法接受的。详细跟进代码,发现用子集构造法会给DFA加入很多无用的边,而每次子集的计算代价都是非常昂贵的。优化了一下算法之后相同表达式只花费了4秒,但仍然不够。算法的问题解决了,但代码仍然有问题。花了2个晚上之后,相同表达式运行时间为0.5秒。
这个性能我仍然不太满意,但由于一开始基于上手,构建的数据结构不太合理,加上大量运用了Java的标准库,继续优化下去已经很难了。要花费大量时间和精力,改动大量代码,那就这样吧。。。
过段时间,要是有空的话,可以尝试一下基于NFA的正则表达式,用C++重构,效率估计又能高很多。
- 正则表达式引擎实现体会
- 简单正则表达式实现引擎
- 正则表达式学习心得体会
- 正则表达式原理及引擎实现
- 简单功能的正则表达式引擎实现
- 正则表达式引擎
- DEELX 正则表达式引擎
- 正则表达式引擎
- 正则表达式的引擎
- 正则表达式有关引擎
- 正则表达式引擎
- 正则表达式引擎浅析
- 正则表达式的引擎
- 正则表达式原理及引擎简化递归实现
- DEELX - Regexp - 正则表达式引擎
- 正则表达式引擎的规则
- 自己动手写正则表达式引擎
- 简单的正则表达式引擎
- Q:suse 11.1上安装R 3.2.2
- LeetCode 310. Minimum Height Trees(最小高度树)
- C# 矩形面积 0002
- hive和hbase表数据同步
- Rule of Three
- 正则表达式引擎实现体会
- 扩展欧几里得算法
- hbase集群安装(1)-ssh安装及配置
- Android的Touch系统简介(一)
- hbase集群安装(2)-ubuntu下jdk安装
- hbase集群安装(3)-安转Hadoop
- 安卓开发中一些小问题
- complementary prior
- Mysql技术内幕——表&索引算法和锁