Java中的正则表达式,其中执行搜索的文本是动态变化的

Java中的正则表达式,其中执行搜索的文本是动态变化的,java,regex,Java,Regex,在Java中,find()+start()+end()可用于提取正则表达式模式,该模式在matcher对象上使用三个函数多次出现 Pattern p = Pattern.compile(regex); Matcher matcher = p.matcher(text); while(matcher.find()){ String subString = text.substring(matcher.start(), matcher.end()); text = text+subS

在Java中,find()+start()+end()可用于提取正则表达式模式,该模式在
matcher
对象上使用三个函数多次出现

Pattern p = Pattern.compile(regex); 
Matcher matcher = p.matcher(text);
while(matcher.find()){ 
   String subString = text.substring(matcher.start(), matcher.end());
   text = text+subString; 
} 
在我的例子中,文本随着while循环中的每个find()而变化,所以下次matcher.start()和matcher.end()会给出错误的索引。我的意思是这些索引对于旧文本是正确的,但是随着文本的变化,它给出了错误的索引。
(这里的文本将在下次start()和end()函数返回不期望的索引时更改)。

如@VGR所述,
Matcher
的实例将只搜索最初给定的字符串。如果要搜索新字符串,则必须创建
Matcher
的新实例。在您的情况下,下一次搜索将从上次匹配后的索引开始。例如:

Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(text);
int start = 0;
while (matcher.find(start)) {
    text = text + text.substring(matcher.start(), matcher.end());
    start = matcher.end();
    matcher = pattern.matcher(text);
}
StringBuilder stringBuilder = new StringBuilder(text);
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(stringBuilder);
int start = 0;
while (matcher.find(start)) {
    stringBuilder.append(stringBuilder, matcher.start(), matcher.end());
    start = matcher.end();
    matcher.reset();
}
text = stringBuilder.toString();
如果您还没有意识到,那么您应该知道
text=text+subString
创建了一个全新的
String
对象,然后将其分配给原始
text
变量。这意味着,尽管
text
引用了“更新的”文本,
matcher
只知道创建
matcher
时引用的
text
对象。这就是为什么对于您的用例,您必须为每个循环创建一个新的
Matcher
实例


可选地,您可以考虑使用,以避免每次迭代创建一个全新的字符串(Matter)的开销。但是,您仍然需要跟踪

开始
索引,因为每次迭代都需要重置
匹配器
对象,以便它识别
StringBuilder
对象的更新/更长的内部结束索引(即追加的文本)。例如:

Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(text);
int start = 0;
while (matcher.find(start)) {
    text = text + text.substring(matcher.start(), matcher.end());
    start = matcher.end();
    matcher = pattern.matcher(text);
}
StringBuilder stringBuilder = new StringBuilder(text);
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(stringBuilder);
int start = 0;
while (matcher.find(start)) {
    stringBuilder.append(stringBuilder, matcher.start(), matcher.end());
    start = matcher.end();
    matcher.reset();
}
text = stringBuilder.toString();


最后,一定要小心。除非您在正则表达式中有一些非常时髦的魔力(这完全是另一个问题),否则如果在文本中找到至少一个模式实例,那么这段代码将永远循环。我建议您在
while
循环中添加一个附加条件或某种计数器。

您的问题不清楚。。请添加更多信息。不便之处,敬请原谅。Pattern p=Pattern.compile(regex);Matcher Matcher=p.Matcher(文本);而(matcher.find()){String subString=text.subString(matcher.start(),matcher.end());text=text+subString;}在这里,下次start()和end()函数返回不期望的索引时,文本正在更改。上面的代码清楚吗?当您调用
p.Matcher(text)
时,匹配器返回的索引仅适用于
text
的值。调用
p.matcher(text)
后,matcher根本看不到您对
text
所做的任何更改。如果
text
更改,您必须创建一个新的匹配器或在现有匹配器上调用reset(text)。非常感谢Travis,这正是我的问题所在。我也尝试过reset(),但有时它会导致无限循环,我发现了这个问题。我所做的与你给出的代码相似。我还使用了appendReplacement()函数。@AnujPandey您到底想做什么?如果这是您的实际代码(循环中没有其他条件),那么我认为您的问题可能在设计级别,而不是代码级别。由于无限循环的危险,此代码永远不应该按原样执行。我只是直接回答你的问题