我有以下周期:
public class Main {
public static void main (String[] args){
String test = "#{value} lorem ipsum #{value} lorem ipsum";
String regex = "(#\\{)([^}]*)(})";
Pattern callPattern = Pattern.compile(regex);
Matcher callMatcher = callPattern.matcher(test);
while (callMatcher.find()) {
test = callMatcher.replaceFirst(generate());
}
System.out.println(test);
}
private static String generate(){
Random random = new Random();
return String.valueOf(random.nextInt(100));
}
}
执行陷入了我的while循环。我过去使用过类似的算法,为什么这个算法被卡住了?它似乎能够替换第一次出现,但随后发现但从未替换第二次出现。
答案 0 :(得分:2)
在你的情况下,匹配器的原因在while
循环中保持相同:
Matcher callMatcher = callPattern.matcher(test);
while (callMatcher.find()) { // same value for matcher
test = callMatcher.replaceFirst(generate()); // you just keep updating the same #{value} everytime
}
将其更改为:
Matcher callMatcher = callPattern.matcher(test);
while (callMatcher.find()) {
test = callMatcher.replaceFirst(generate());
callMatcher = callPattern.matcher(test); // updates the matcher with replaced text
}
答案 1 :(得分:2)
您也可以完全避免使用匹配器,而只需依赖基本字符串函数String#matches
和String#replaceFirst
:
String test = "#{value} lorem ipsum #{value} lorem ipsum";
while (test.matches(".*#\\{[^}]*\\}.*")) {
test = test.replaceFirst("#\\{[^}]*\\}", generate());
}
System.out.println(test);
<强>输出:强>
87 lorem ipsum 57 lorem ipsum
在这里演示:
答案 2 :(得分:0)
问题并非那么简单。在这段代码中确实如此:
elementList = [g1, g2, g3, g4, g5]
for num in range(len(elementList)):
if num == 0:
temp = elementList[num]
else:
temp = temp + elementList[num]
分配给 Matcher callMatcher = callPattern.matcher(test);
while (callMatcher.find()) {
test = callMatcher.replaceFirst(generate());
不会替换匹配器中的字符串。
但是,这并不能完全解释这种情况,因为test
通常会找到匹配的 next 。取决于callMatcher.find()
循环体内的内容,这意味着while
循环可能仅执行两次。那么为什么在这种情况下无限循环?
它与重置的匹配器有关。 while
的{{3}}说:
此方法从此匹配器区域的开头开始,或者,如果是 以前的方法调用是成功的,匹配器有 从没有重置,在第一个字符不匹配 上一场比赛。
句子的后半部分意味着如果未重置匹配器,则find()
将找到该模式的 next 出现,这意味着find()
将只能成功两次,然后find()
循环将退出。但是javadoc对while
中的replaceFirst()
说明了这一点:
此方法首先重置此匹配器。
因此,由于匹配器已重置,Matcher
每次都会从头开始搜索,而不是最后一次匹配的位置。这可以解释您的评论中的问题,关于代码在其他地方工作的原因。可能是你没有调用任何重置匹配器的东西。
处理这种情况的最佳方法,就是使用find()
和appendReplacement
来替换每个模式的情况。 appendTail
的{{3}}有一个很好的示例,展示了如何使用它。