java.util.regex.Matcher.find()人的Javadoc说:

此方法从此匹配器区域的开始处开始,或者,如果 上一次调用该方法是成功的,并且匹配器已经 属性不匹配的第一个字符 上一场比赛.

我自己的实验表明,如果正则表达式匹配一个零长度字符串,那么该方法将从前一个(零长度)匹配的结尾开始一个字符.例如,给定输入字符串"abCabc"和正则表达式"a|b?",将在位置(0,1,2,3,4,5,6)进行连续匹配.在位置6处匹配成功之后,在位置6处匹配不成功;并且进一步的调用也返回FALSE,位置保持在6处.

文档建议,在位置2(字符"c")找到零长度匹配后,对Find的下一次调用将从"第一个字符不匹配"开始,它仍然位于位置2.

文档还建议,在位置6匹配失败后,下一次调用应从位置0开始,但情况似乎并非如此.

文档是不是完全错了?

有没有更精确的规则,例如涵盖第六位行为的规则?

我问这个问题的原因是,我正在try 用C#编写该方法的模拟,而通过反复试验来重现准确的行为时遇到了困难.

推荐答案

这是一个由Matcher.find()人处理的特例:

public boolean find() {
    int nextSearchIndex = last;
    if (nextSearchIndex == first)
        nextSearchIndex++;

    // If next search starts before region, start it at region
    if (nextSearchIndex < from)
        nextSearchIndex = from;

    // If next search starts beyond region then it fails
    if (nextSearchIndex > to) {
        for (int i = 0; i < groups.length; i++)
            groups[i] = -1;
        return false;
    }
    return search(nextSearchIndex);
}

如果最后一个匹配是零长度匹配(用first == last表示),则它在last + 1处开始下一次搜索.

如果你仔细想想,这是有道理的.如果没有这一点,如果Matcher一旦找到零长度匹配,它将永远不会超过这一匹配.


因此,是的,文档是不完整的:它既没有提到零长度匹配的特殊情况,也没有提到它只对输入字符串传递一次.

但是,这两种特殊情况都隐含在"try 找到与模式匹配的输入序列的next subsequence"中.

在零长度匹配之后,下一个可能的子序列必须在前一个匹配之后的一个位置开始,并且下一个子序列永远不能从低于当前位置的位置开始(即从开始处开始).

Java相关问答推荐

是否可以从@ TrustMapping中删除特定方法的基路径?

当一个链表中间有一个循环时,它的松散部分会发生什么?

try 使用Java 9或更高版本对特殊对象图进行解析时出现NullPointerException

如何转换Tue Feb 27 2024 16:35:30 GMT +0800 String至ZonedDateTime类型""

RESTful框架类字段是安全的还是不安全的

将带有js文件的 bootstrap 程序导入maven项目时出错

通过移动一个类解决了潜在的StubbingProblem.它怎麽工作?

将java.util.Date转换为OffsetDateTime

如何对多个字段进行分组和排序?

如何在一行中使用Dijkstra中的Java Stream

在学习Spring时,通过构造函数参数0表达了不满意的依赖关系

如何在JavaFX循环中完美地制作一个AudioClip/MediaPlayer?

将ByteBuffer异步写入InputStream或Channel或类似对象

try 使用类来包含JSON响应

如何通过用户ID向用户发送私信

如何在Spring Boot Auth服务器上正确配置CORS?

如何使用带有可选参数的类生成器?

如何在java中从以百分比表示的经过时间和结束日期中找到开始日期

带有提取器的JavaFXObservableList会根据侦听器的存在而改变行为

为什么 Random() 的行为不符合预期?