Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何引用重复的嵌套捕获组?_Java_Regex - Fatal编程技术网

Java 如何引用重复的嵌套捕获组?

Java 如何引用重复的嵌套捕获组?,java,regex,Java,Regex,我正在编写Java代码,最近将这个actions类列表中的一些方法委托给了一个BasicActions类,现在我想更新这个类中的所有方法,以引用BasicActions方法。我正在更新的方法和我希望它们引用的方法具有相同的名称和参数,我尝试使用regex重写代码,但我不知道如何处理方法参数,其中可能有任意数量的参数,我不能简单地复制组,因为我需要从中删除关键字 Example input: public void jumpTo(final double x, double y) { /*

我正在编写Java代码,最近将这个actions类列表中的一些方法委托给了一个BasicActions类,现在我想更新这个类中的所有方法,以引用BasicActions方法。我正在更新的方法和我希望它们引用的方法具有相同的名称和参数,我尝试使用regex重写代码,但我不知道如何处理方法参数,其中可能有任意数量的参数,我不能简单地复制组,因为我需要从中删除关键字

Example input:
public void jumpTo(final double x, double y) {
    /*arbitrary code,
    possibly spanning multiple lines*/
}
Desired output:
public void jumpTo(double x, double y) {
    addAction(BasicActions.jumpTo(x, y));
}
Almost-correct solution:
pattern: (public void ([a-zA-Z]*)\(((final )?([a-zA-Z]+) ([a-zA-Z]+(, )?))*\) \{\n *)((.*\n)*?)(    })
replacement: $1addAction(BasicActions.$2($6));\n$10
Almost-correct output: (doesn't remove unnecessary 'final' keywords, only captures the final argument)
public void jumpTo(final double x, double y) {
    addAction(BasicActions.jumpTo(y));
}
请参阅上的“几乎解决方案”


我的问题是,因为我不能包含type关键字(
double
,在本例中),我必须拆分变量名,然后多次捕获它们。如何访问多个捕获,或者在复制多个参数时重新格式化这些参数?

重复捕获组时,只捕获最后一项。使用正则表达式

public void ([a-zA-Z]*)\((?:(?:final )?[a-zA-Z]+ ([a-zA-Z]+(?:, )?))*\)  
其中(?:)用于避免不必要的捕获复杂性和地狱中的编号,$0表示全部,$1表示“跳转”,而$2表示“y”。不幸的是,x不能以这种方式捕获

您可能需要分解正则表达式,通过多次重复参数匹配,我在这里做了3次(您可能需要更多)

公共空间([a-zA-Z]*)((?:(?:最终版);[a-zA-Z]+(?:,))(?:(?:最终版);[a-zA-Z]+([a-zA-Z]+(?:,)最终版);(?:(?:最终版);[a-zA-Z]+(?:,)?)

$1为“跳转”,$2为“x”,$3为“y”,$4为空

编号很简单,因为不计算非捕获组

/*任意代码*/可以使用更简单的匹配非捕获规则

\{(?:.|\n)*?\n    \} 
以及替换规则

{\n    addAction(BasicActions.$1($2$3$4$5$6$7));\n    }\n
最终的regexp(最多6个参数)将是(在多行上拆分)

(?x: header match starts from here)
(public void ([a-zA-Z]*)\(
(?:(?:final )?[a-zA-Z]+ ([a-zA-Z]+(?:, )?))?(?x: param 1)
(?:(?:final )?[a-zA-Z]+ ([a-zA-Z]+(?:, )?))?(?x: param 2)
(?:(?:final )?[a-zA-Z]+ ([a-zA-Z]+(?:, )?))?(?x: param 3)
(?:(?:final )?[a-zA-Z]+ ([a-zA-Z]+(?:, )?))?(?x: param 4)
(?:(?:final )?[a-zA-Z]+ ([a-zA-Z]+(?:, )?))?(?x: param 5)
(?:(?:final )?[a-zA-Z]+ ([a-zA-Z]+(?:, )?))?(?x: param 6)
\))
(?x: match body starts here) \{(.|\n)*?\n    \}
()()()()()()(?x: for missing params 1-6)
在哪里

$1是原始函数原型

$2是取自函数名的名称

$3是第一个参数(或空字符串)

$4是第二个参数(或空字符串)

$5是第三个参数(或空字符串)

使用更长的正则表达式很容易扩展到4,5,6,7,…参数,并且在计算捕获组时没有问题。最后一个()()…确保捕获组为空,而不管参数的数量如何(这取决于正则表达式引擎的实现)。一些正则表达式引擎可能不喜欢空(),但很少有人检测到空字符串的自愿匹配

((?x:))
将regexp注释添加到捕获组中


(由于拼写错误和外观原因,编辑了很多次,(.|\n)是半盲半盲阅读复杂正则表达式的笑脸)

除了顺序中的最后一个之外,不可能引用重复的捕获组;因此,如果要修改每个捕获组,如在这种情况下,必须按顺序应用多个正则表达式:

步骤1:将参数列表复制到位置()

步骤2:删除
final

pattern:final #note the space
replacement:
output:
public void jumpTo(double x, double y) {
    addAction(BasicActions.jumpTo(double x, double y));
}
步骤3:删除类型关键字()


不能使用正则表达式返回重复捕获组。如果在捕获组后放置类似
*
+
{1,5}
的内容,则
组(n)
方法将为您提供组匹配的源的最后一个子字符串。(这同样适用于替换字符串中的
$
,该字符串使用
组(n)
)该组匹配的任何早期子字符串都将丢失。抱歉。如果您所要求的与此无关,那么我不理解您的要求。很难理解您的需要。您无法使用regexp处理嵌套的{}()[]..,对于包含部分代码的注释也会非常复杂。您可以插入addAction()调用,并插入返回语句,并且不应尝试匹配“.任意代码,可能跨越多行”使用正则表达式….@Pierre,代码的格式很好;可以安全地假设代码以包含四个空格和一个右括号的行结尾,就像在我的解决方案中一样。
pattern:final #note the space
replacement:
output:
public void jumpTo(double x, double y) {
    addAction(BasicActions.jumpTo(double x, double y));
}
use lookahead to match any argument without passing over other arguments
pattern: \w+ (\w+)(?=(, \w+ \w+)*\)\);\n    })
replacement: $1
output:
public void jumpTo(double x, double y) {
    addAction(BasicActions.jumpTo(x, y));
}