按文件将文本脚本拆分为子字符串

时间:2010-10-14 12:41:35

标签: java regex string string-parsing

考虑下面的脚本(它是伪语言的完全废话):

if (Request.hostMatch("asfasfasf.com") && someString.existsIn(new String[] {"brr", "hrr"}))   {
    if (Requqest.clientIp("10.0.x.x")) {
        somevar = "1";
    }
    somevar = "2";
}
else {
    somevar = "first";
}
string foo = "foo";
// etc. etc.

你如何从中获取if-block的参数和内容? if-block的格式为:

if<whitespace>(<parameters>)<whitespace>{<contents>}<anything>

我尝试使用String.split()的正则表达式^if\s*\(|\)\s*\{|\}\s*,但这种情况很糟糕。也就是说,问题是在内部if-block中也发现) {,并且在许多地方也发现了结束}。我不认为懒惰或急切的扩张在这里起作用。

那么......为了用regex实现这个,我需要指点什么呢?

我还需要在没有if-block代码的情况下获取剩余的字符串(所以代码从else { ...开始)。仅使用String.split()似乎很难,因为没有关于被解析的部分长度的信息。

我最初为此创建了一个基于循环的解决方案(大量使用String.substring()),但它很无聊。我希望有更好的东西。我应该使用正则表达式还是创建一个自定义的泛型函数(除此之外还有很多其他情况)采用可解析的字符串和模式(考虑上面的if<whitespace>(...模式)?

编辑:更改了返回变量赋值,否则就没有意义了。

3 个答案:

答案 0 :(得分:2)

使用(或编写)解析器要比使用Regex执行此操作要好得多。

正则表达式非常适合某些人,但对于像这样的复杂解析,它很糟糕。另一个很糟糕的例子就是解析HTML - 你可以在有限的程度上完成它,但对于任何复杂的东西,DOM解析器都是一个更好的解决方案。

对于[非常]简单的解析器,你需要的是一个递归函数,它会搜索大括号{},每次遇到一个开括号时递归一个级别,然后返回找到一个右括号时备份一个级别。然后它需要在每个级别的两个大括号之间存储字符串内容。

答案 1 :(得分:1)

常规语言不起作用,因为regular grammar无法匹配诸如“任意数量的左括号后跟任意数量的近括号”之类的内容。为此需要context-free grammar

除非您使用context-free grammar parser for Javamakes regular expressions no longer regular的正则表达式扩展名,否则基于循环的解决方案可能是最有效的解决方案。

答案 2 :(得分:1)

根据以上所述,您需要一个解析器。一种易于实现(并且编写有趣!)的类型是recursive descent parser with backtracking。还有很多解析器生成器,尽管其中大多数都有学习曲线。一个对Java友好的解析器生成器是JavaCC