Java Regex替换为匹配的计数
我想用匹配的编号/索引替换匹配 java正则表达式中是否有方法知道当前匹配的匹配号,以便我可以使用Java Regex替换为匹配的计数,java,regex,Java,Regex,我想用匹配的编号/索引替换匹配 java正则表达式中是否有方法知道当前匹配的匹配号,以便我可以使用String.replaceAll(regex,replacement) 示例:用自身及其索引替换[A-Z]: Input: fooXbarYfooZ Output: fooX1barY2fooZ3 这通电话: "fooXbarXfooX".replaceAll("[A-Z]", "$0<some reference to the match count>"); “fooXbarX
String.replaceAll(regex,replacement)
示例:用自身及其索引替换[A-Z]
:
Input: fooXbarYfooZ
Output: fooX1barY2fooZ3
这通电话:
"fooXbarXfooX".replaceAll("[A-Z]", "$0<some reference to the match count>");
“fooXbarXfooX”.replaceAll(“[A-Z]”,“$0”);
应返回“fooX1barY2fooZ3”
注意:我正在寻找一个替代字符串,如果存在的话,它可以做到这一点
请不要提供涉及循环或类似代码的答案。
编辑: 我会接受最优雅的有效答案(即使它使用循环)。没有当前答案
实际工作。需要对输入字符串进行迭代,因此不可避免地会以这种或那种方式循环。标准API未实现实现该循环的方法,因此该循环必须位于客户端代码中或第三方库中
下面是代码的外观,顺便说一句:
public abstract class MatchReplacer {
private final Pattern pattern;
public MatchReplacer(Pattern pattern) {
this.pattern = pattern;
}
public abstract String replacement(MatchResult matchResult);
public String replace(String input) {
Matcher m = pattern.matcher(input);
StringBuffer sb = new StringBuffer();
while (m.find())
m.appendReplacement(sb, replacement(m.toMatchResult()));
m.appendTail(sb);
return sb.toString();
}
}
用法:
public static void main(String... args) {
MatchReplacer replacer = new MatchReplacer(Pattern.compile("[A-Z]")) {
int i = 1;
@Override public String replacement(MatchResult m) {
return "$0" + i++;
}
};
System.out.println(replacer.replace("fooXbarXfooX"));
}
输出:
fooX1barX2fooX3
在Java中没有循环是不可能的…我认为在Java中没有任何循环是不可能的
String x = "fooXbarXfooX";
int count = 0;
while(x.contains("X"))
x = x.replaceFirst("X", Integer.toString(count++));
System.out.println(x);
Java正则表达式不支持对匹配计数的引用,因此这是不可能的。没有简单的替换字符串可以做到这一点;字符串不能存储状态,并且正则表达式引擎也没有内置的方式来存储状态。我认为您需要一些启用堆栈的正则表达式,我认为Java正则表达式没有…您想要这样的东西:。一般来说,我不知道有哪种正则表达式风格允许在没有回调的情况下进行“本地”替换:“无循环”需求从何而来?我不明白:几乎所有事情都涉及循环,包括解释正则表达式。那么你真正想要实现什么呢?你想避免看到循环吗?@Bohemian,不,标准JDK不提供这种功能。如果您在方法中排除替换代码,您的代码应该不会显得凌乱。问题:请不要提供涉及循环或类似代码的答案。即使是循环,也很好。但是,请注意编辑到问题改进示例以演示匹配和替换必须是正则表达式,这将破坏现有的实现,因为
replacement()
的结果必须使用反向引用。我看不出它如何破坏当前解决方案。appendReplacement
方法可以(就像replaceAll
)处理像$0
这样的反向引用。更新了main
方法以显示如何完成。一些反馈:虽然它的代码比其他解决方案少,但因为您要重新启动regex match every循环,因此存在regex匹配替换的风险,从而导致无限循环。考虑一下当用<代码> >“席”<代码>代替<代码>“X”/代码>时,代码<>代码>第一个>代码> x>代码>将永远匹配。您可以通过在上次匹配的位置之后开始匹配来避免这种情况,但随后您的代码将变形为类似dacwe的代码。而且,他的代码效率更高,因为它只进行一次传递。只是需要考虑一下。请注意编辑问题细化示例以演示匹配和替换必须是正则表达式。