4

我想使用正则表达式替换函数定义和声明,即

代替

public abstract void myFuction(MyParam myParam);

或者

@Override
public void myFuction(MyParam myParam){

}

我试过这个正则表达式:

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

但问题是如果该功能有任何其他功能,{否则}它将无法正常工作。

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

4

3 回答 3

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 不支持,afaik PHP 和 Perl 支持),您必须:

  • 预测最大嵌套级别;或者
  • 自己创建一个解析器。

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

也就是说,使用R运算符将​​是这样的:

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

此答案的更多信息。

于 2013-04-11T05:13:37.093 回答
1

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

([\t\s]+)@Override.*?\n\1}
于 2013-04-11T05:11:26.383 回答
0

恐怕仅使用正则表达式是不可能的。

如果您理解正确,您需要重新格式化一些语法,并且我认为代码必须仍然是可编译的,在这种情况下,您需要计算每个增加{和减少的数量,}以便您知道函数何时结束。一种替代方法可能是在面临下一个声明时返回到第一个找到}的位置,但是会有很多异常需要处理,例如课程结束时等...

我建议您使用 Java 源代码解析来完成这项工作,它能够将方法识别为方法,并且可以为您节省大量工作,例如看看javaparser

于 2013-04-11T05:10:45.943 回答