有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

在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()而变化,所以下次匹配器。start()和matcher。end()给出了错误的索引。我的意思是这些索引对于旧文本是正确的,但是随着文本的变化,它给出了错误的索引。 (这里的文本将在下次start()和end()函数返回不期望的索引时更改)


共 (1) 个答案

  1. # 1 楼答案

    正如@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);
    }
    

    如果您还没有意识到,那么您应该知道text = text + subString创建了一个全新的String对象,然后将其分配给原始的text变量。这意味着,尽管text引用了“更新的”文本,matcher只知道在创建matcherString引用的text对象。这就是为什么对于您的用例,您必须为每个循环创建一个新的Matcher实例


    可选地,您可以考虑使用{A1},以避免每次迭代创建一个全新的字符串(Matter)的开销。不过,您仍然需要跟踪start索引,因为每次迭代都需要重置Matcher对象,以便它识别StringBuilder对象的更新/更长的内部结束索引(即附加文本)。例如:

    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循环上添加一个附加条件或某种计数器