使用正则表达式替换java函数:匹配嵌套括号

时间:2013-04-11 04:51:14

标签: java regex

我想用Regex替换函数定义和声明,即

替换

public abstract void myFuction(MyParam myParam);

@Override
public void myFuction(MyParam myParam){

}

我试过这个正则表达式:

(@Override[\n\s\t]*)?public *(abstract)? *void
*generateProcessMethod *\(UIGenerationContext *[^)]+\)[\n\\s\t]*((\{[^{}]*?\})|;)

但问题是,如果该函数有任何其他{},那么它将无效。

[^{}]替换.不是解决方案,因为它也取代了以下功能。

3 个答案:

答案 0 :(得分:6)

使用正则表达式,这个(括号嵌套)可以可以完成,但只能达到固定的嵌套级别。

您当前的正则表达式(稍有改动):

(@Override[\n\s\t]*)?public *(abstract)? *void *[a-z]*\([a-z]* [^)]+\)[\n\\s\t]*((\{[^\{\}]*?\})|;)

只允许一个级别。更具体地说,这是匹配它的部分:

(\{[^\{\}]*?\})

如果您想匹配最多两个级别,请将提及的部分更改为:

(\{([^{}]*|\{[^{}]*\})*\})

因此:

(@Override[\n\s\t]*)?public *(abstract)? *void *[a-z]*\([a-z]* [^)]+\)[\n\\s\t]*(\{([^{}]*|\{[^{}]*\})*\}|;)

要添加更多关卡,您必须继续编辑。当你添加关卡时,变得更加混乱和混乱。

<强>解释

  • \{将匹配第一个左括号
    • (打开一个群组
      • [^{}]*匹配括号
      • 以外的任何内容
      • |
      • \{如果确实找到了一个开头括号......
        • [^{}]* ...它将匹配括号以外的任何内容......
      • \} ...直到找到结束括号
    • )关闭群组
    • *上述群组可能会发生零次或多次
  • \}匹配结束括号

要添加更多关卡,请将中间(第二个)[^{}]*部分更改为([^{}]*|\{[^{}]*\})*

如果无法预测最大嵌套级别:

有些语言允许嵌套操作符R,它允许您嵌套任意数量的级别。如果你的语言不支持它(Java不支持PHP和Perl那么做),你必须要么:

  • 预测最大嵌套水平; OR
  • 自己创建一个解析器。

正则表达式,没有R运算符,不能嵌套任意数量的级别。

尽管如此,使用R运算符将是这样的:

(\{([^{}]|(?R))*\})

this answer的更多信息。

答案 1 :(得分:1)

正则表达式不擅长处理嵌套组件。但是,如果您知道@Override将缩进与结束括号相同并且其所有内容都进一步缩进的事实,您可以使用此:

([\t\s]+)@Override.*?\n\1}

答案 2 :(得分:0)

我担心仅使用RegExpressions是不可能的。

如果你理解正确,你需要重新格式化一些语法,我认为代码必须仍然是可编译的,在这种情况下,你需要计算每个{的增加量,并减少每个}的代价。你知道什么时候功能结束。一旦你面对下一个声明,一个替代方法可能是回到第一个找到的},但是当类结束等时会有很多异常处理......

我建议您使用Java源解析该作业,它可以将方法识别为方法,并且可以省去大量工作,例如javaparser看看