java 如何在匹配器组而不是整个模式上追加替换?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3940195/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 04:03:32  来源:igfitidea点击:

How to appendReplacement on a Matcher group instead of the whole pattern?

javaregexappendmatcher

提问by cottonBallPaws

I am using a while(matcher.find())to loop through all of the matches of a Pattern. For each instance or match of that pattern it finds, I want to replace matcher.group(3)with some new text. This text will be different for each one so I am using matcher.appendReplacement()to rebuild the original string with the new changes as it goes through. However, appendReplacement()replaces the entire Pattern instead of just the group.

我正在使用 awhile(matcher.find())来遍历模式的所有匹配项。对于它找到的该模式的每个实例或匹配项,我想matcher.group(3)用一些新文本替换。每个文本都会有所不同,因此我将使用matcher.appendReplacement()新的更改来重建原始字符串。但是,appendReplacement()替换整个 Pattern 而不仅仅是组。

How can I do this but only modify the third group of the match rather than the entire Pattern?

我怎样才能做到这一点,但只修改匹配的第三组而不是整个模式?

Here is some example code:

下面是一些示例代码:

Pattern pattern = Pattern.compile("THE (REGEX) (EXPRESSION) (WITH MULTIPLE) GROUPS");
Matcher matcher = pattern.matcher("THE TEXT TO SEARCH AND MODIFY");
StringBuffer buffer = new StringBuffer();

while(matcher.find()){
   matcher.appendReplacement(buffer, processTheGroup(matcher.group(3));
}

but I would like to do something like this (obviously this doesn't work).

但我想做这样的事情(显然这行不通)。

...
while(matcher.find()){
   matcher.group(3).appendReplacement(buffer, processTheGroup(matcher.group(3));
}

Something like that, where it only replaces a certain group, not the whole Pattern.

类似的东西,它只替换某个组,而不是整个 Pattern。

EDIT: changed the regex example to show that not all of the pattern is grouped.

编辑:更改了正则表达式示例以显示并非所有模式都已分组。

采纳答案by polygenelubricants

Let's say your entire pattern matches "(prefix)(infix)(suffix)", capturing the 3 parts into groups 1, 2 and 3 respectively. Now let's say you want to replace only group 2 (the infix), leaving the prefix and suffix intact the way they were.

假设您的整个模式匹配"(prefix)(infix)(suffix)",分别将 3 个部分捕获到组 1、2 和 3 中。现在假设您只想替换第 2 组(中缀),保持前缀和后缀保持原样。

Then what you do is you append what group(1)matched (unaltered), the new replacement for group(2), and what group(3)matched (unaltered), so something like this:

然后你要做的是附加group(1)匹配的(未改变的),新的替换group(2),以及group(3)匹配的(未改变的),所以是这样的:

matcher.appendReplacement(
    buffer,
    matcher.group(1) + processTheGroup(matcher.group(2)) + matcher.group(3)
);

This will still match and replace the entire pattern, but since groups 1 and 3 are left untouched, effectively only the infix is replaced.

这仍将匹配并替换整个模式,但由于组 1 和 3 保持不变,因此实际上只替换了中缀。

You should be able to adapt the same basic technique for your particular scenario.

您应该能够为您的特定场景调整相同的基本技术。

回答by Warren

I see this already has an accepted answer, but it is not fully correct. The correct answer appears to be something like this:

我看到这已经有一个公认的答案,但它并不完全正确。正确答案似乎是这样的:

.appendReplacement("" + process(m.group(2)) + "");

This also illustrates that "$" is a special character in .appendReplacement. Therefore you must take care in your "process()" function to replace all "$" with "\$". Matcher.quoteReplacement(replacementString) will do this for you (thanks @Med)

这也说明“$”是 .appendReplacement 中的一个特殊字符。因此,您必须小心使用“process()”函数将所有“$”替换为“\$”。Matcher.quoteReplacement(replacementString) 会为你做这件事(感谢@Med)

The previous accepted answer will fail if either groups 1 or 3 happen to contain a "$". You'll end up with "java.lang.IllegalArgumentException: Illegal group reference"

如果第 1 组或第 3 组碰巧包含“$”,则先前接受的答案将失败。你最终会得到“java.lang.IllegalArgumentException: Illegal group reference”