在编写具有查找和替换功能的文本编辑器时,用户可以多次搜索然后替换。在Java中,搜索部分非常简单:
Pattern pattern = Pattern.compile(userInput);
...
String line = ...
Matcher matcher = pattern.matcher(line);
int from = 0;
while (from < line.length() && matcher.find(from)) {
int start = matcher.start();
int length = matcher.end() - start;
// pseudo-code:
if (askUser()) {
return ...
}
from = start + 1;
}
但是如何处理替换第n场比赛? Matcher
有replaceAll
和replaceFirst
。第一个显然不合适,但对于replaceFirst
文档说:
用与给定替换字符串匹配的模式替换输入序列的第一个子序列。 此方法首先重置此匹配器。然后扫描输入序列以查找模式的匹配。
大胆的句子让我担心这是否合适。我需要用某种模式替换当前的匹配。
答案 0 :(得分:6)
如果您想要替换特定匹配项,请多次调用find()
并使用start()
和end()
方法替换匹配的部分。
StringBuilder builder = new StringBuilder(stringToMatch);
Matcher m = Pattern.compile(yourRegex).matcher(stringToMatch);
for (int i = 0 ; i < n ; i++) { // n is the nth match you want to replace
m.find();
}
builder.replace(m.start(), m.end(), yourReplacement);
答案 1 :(得分:1)
如果要使用完整的Matcher.replaceFirst
语法(包括对捕获组的可能引用)进行替换,可以查看replaceFirst
的来源。它在Matcher
中调用了两种公共方法:appendReplacement
和appendTail
。您可以在没有先重置匹配器且不进行find
调用的情况下调用它们:
StringBuffer sb = new StringBuffer();
matcher.appendReplacement(sb, replacement);
matcher.appendTail(sb);
这导致带有输入字符串的新Stringbuffer,除了当前匹配被替换字符串替换(可以包含对捕获组的引用)