gpt4 book ai didi

java - 使用 Matcher.appendReplacement() 时区域似乎被忽略

转载 作者:行者123 更新时间:2023-11-30 10:58:33 26 4
gpt4 key购买 nike

我正在使用 jdk1.7.0_79 尝试用 Matcher 替换一些文本。我大量使用了 Matcher.appendReplacement()Matcher.appendTail(),当我没有设置区域时一切正常。

如果我在 Matcher.find() 循环之前使用 Matcher.region(startPosition, endPosition),第一个 Matcher.appendReplacement() 方法将从输入文本的开头追加所有输入到匹配的元素,而我希望它从区域开始位置开始。

我查看了 Matcher 源代码,实现似乎证实了这种行为:lastAppendPositionMatcher.region() 中被重置为 0,并用作Matcher.appendReplacement()Matcher.appendTail() 也是如此。

有人可以确认这是预期的行为吗?我应该在使用区域时自己处理事情吗?为什么会这样,因为将 lastAppendPosition 设置为 Matcher.region() 中的区域开始位置很简单?

我没有展示我的代码,因为它非常复杂。如果需要,我可能会准备一个简单的测试用例。

编辑:添加测试

package test;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TestMatcher {

public static void main(String[] args) {
String inputText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas eu blandit sapien.";
int regionStartPos = 6;
int regionEndPos = inputText.length()-7;
Pattern pattern = Pattern.compile("elit");
Matcher matcher = pattern.matcher(inputText);
StringBuffer result = new StringBuffer();
matcher.region(regionStartPos, regionEndPos);
System.out.println("Region start = " + matcher.regionStart());
System.out.println("Region end = " + matcher.regionEnd());
System.out.println("Skipped beginning = " + inputText.substring(0, regionStartPos));
System.out.println("Skipped ending = " + inputText.substring(regionEndPos, inputText.length()));
matcher.find();
matcher.appendReplacement(result, "ELIT");
matcher.appendTail(result);
System.out.println(result);
}

}

上面的代码给出了以下结果。可以看到,最终输出包含了区域外的部分:

Region start = 6
Region end = 77
Skipped beginning = Lorem
Skipped ending = sapien.
Lorem ipsum dolor sit amet, consectetur adipiscing ELIT. Maecenas eu blandit sapien.

最佳答案

可能有一些用例,其中 appendReplacement 和 appendTail 在实现时很有用,即忽略区域,但在我的例子中它们不是。如果实现允许我通过某个地方的简单标志来选择它的行为,我会非常高兴。缺乏这一点,这就是我为需要尊重地区的人们想出的解决方法。

  1. 在定义区域之后,调用 fixRegion(),如果需要,它将更新 lastAppendPosition;
  2. 不调用 Matcher.appendTail(),而是使用新的 appendTail() 方法

下面是更新后的测试

package test;

import java.lang.reflect.Field;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TestMatcher {

public static void main(String[] args) throws Exception {
String inputText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas eu blandit sapien.";
int regionStartPos = 6;
int regionEndPos = inputText.length()-7;
Pattern pattern = Pattern.compile("elit");
Matcher matcher = pattern.matcher(inputText);
StringBuffer result = new StringBuffer();
matcher.region(regionStartPos, regionEndPos);
fixRegion(matcher); // ADDED
System.out.println("Region start = " + matcher.regionStart());
System.out.println("Region end = " + matcher.regionEnd());
System.out.println("Skipped beginning = " + inputText.substring(0, regionStartPos));
System.out.println("Skipped ending = " + inputText.substring(regionEndPos, inputText.length()));
matcher.find();
matcher.appendReplacement(result, "ELIT");
// matcher.appendTail(result);
appendTail(matcher, inputText, result); // ADDED
System.out.println(result);
}

private static void fixRegion(Matcher m) throws Exception {
Field lastAppendPositionField = Matcher.class.getDeclaredField("lastAppendPosition");
lastAppendPositionField.setAccessible(true);
int lastAppendPosition = (int) lastAppendPositionField.get(m);
if (lastAppendPosition==0) {
lastAppendPositionField.set(m, m.regionStart());
}
}

private static void appendTail(Matcher m, String input, StringBuffer result) throws Exception {
Field lastAppendPositionField = Matcher.class.getDeclaredField("lastAppendPosition");
lastAppendPositionField.setAccessible(true);
int lastAppendPosition = (int) lastAppendPositionField.get(m);
if (lastAppendPosition<m.regionStart()) {
lastAppendPosition = m.regionStart();
}
result.append(input.substring(lastAppendPosition, m.regionEnd()));
}


}

输出:

Region start = 6
Region end = 77
Skipped beginning = Lorem
Skipped ending = sapien.
ipsum dolor sit amet, consectetur adipiscing ELIT. Maecenas eu blandit

关于java - 使用 Matcher.appendReplacement() 时区域似乎被忽略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32206168/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com