利用递归匹配寻找函数体

2019-08-27 21:42:16 +08:00
 liangxiaowen

背景

我在尝试利用 python 正则表达式解析 java 文件。

目前遇到的问题

因为函数体中可能出现多重{},因此采用 python 的 regex。 regex.findall(r'{(?>[^{}]|(?R))}',java_file)

    public void fun(int n) {
        if(n > 1) {
            if (n == 2) {
              n = 3;  
            }
        }
    }

确实能匹配到

 {
        if(n > 1) {
            if (n == 2) {
              n = 3;  
            }
        }
    }

可我需要前面的public 和函数名fun。 在使用 public.*?{(?>[^{}]|(?R))}时,没能匹配到。

甚至使用 public{(?>[^{}]|(?R))}去匹配

    public{
        ...
    }

仍然不能匹配到。

在递归匹配式前后加东西如何实现 我对递归匹配不是很熟悉,希望***指点一下***。

3420 次点击
所在节点    正则表达式
8 条回复
thedrwu
2019-08-27 21:46:33 +08:00
regex 从简单的慢慢调。
然而上下文无关的语法已经超出了正则的表达,加上递归也是有限的(比如注释里、字符串里有不对称的括号)。
momocraft
2019-08-27 21:48:56 +08:00
对自己好一点 学点形式语言的知识吧
Buges
2019-08-27 21:50:04 +08:00
我想到的思路就是,既然你解析 java 源文件,那就像 java 一样解析。
比如先把注释忽略,执行转义,提取字符串等等。
实在不行就去看看 jdk 源码里对语意是如何处理的。
liangxiaowen
2019-08-27 21:58:11 +08:00
@thedrwu 注释已经有工具解决了。
GeruzoniAnsasu
2019-08-27 21:59:56 +08:00
用正则去匹配编程语言的结构明显是编译原理完全没看过的思路

建议从递归下降这个词开始搜
liangxiaowen
2019-08-27 22:15:09 +08:00
语法树的分析应该更适合我,虽然会比正则匹配更复杂。
ipwx
2019-08-27 22:43:07 +08:00
请使用 pyparsing 这个库,而且 Java 很可能有 user contributed example
aguesuka
2019-08-28 10:48:50 +08:00
上下文无关法则可以表达正则不能表达的语法。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/595665

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX