请证明正则表达式 Java 程序中的输出

Please justify the output in Regex Java program

我遇到过一个 Java 正则表达式程序。

程序代码如下:

import java.util.regex.*;

public class Regex_demo01 {

    public static void main(String[] args) {
        boolean b=true;
        Pattern p=Pattern.compile("\d*");
        Matcher m=p.matcher("ab34ef");

        while(b=m.find())
        {
            System.out.println(b);
            System.out.println(">"+m.start()+"\t"+m.group()+"<");
        }


    }

}

输出:

true
>0  <
true
>1  <
true
>2  34<
true
>4  <
true
>5  <
true
>6  <

疑问:众所周知,find()方法returns如果匹配到并记住匹配的起始位置,则为true。如果find() returns true,可以调用start()方法获取匹配的起始位置,调用group()方法获取代表匹配的源数据实际位的字符串被匹配。 我的问题是,当字符串索引到索引 5 时,为什么输出“>6 <”?

Anser 很简单。 x* 匹配任意数量的 x 甚至 0.

* 替换为 +,这与剩下的 1 个或多个元素相匹配。

星号量词(*)定义为"zero or more times"。也就是说,您的模式大部分时间都匹配零位数字。

你真正想要的可能是加量词(+),意思是"one or more times".

来源:https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html


Why is there a match at index 6?

RegEx 不适用于字符基础,而是介于单个字符之间。匹配空字符串时,它会在每个字符之前和之后查找。当然,重复的结果会被忽略,因此在第一个字符之后和第二个字符之前的空字符串将产生一个匹配项而不是两个匹配项。默认情况下,算法是贪心的,这意味着它会匹配尽可能多的字符。

考虑这个例子:

输入字符串是1

正则表达式是 \d*

在这种情况下,RegEx 引擎在第一个字符之前启动并尝试匹配 零、一个或多个数字。由于它很贪心,所以它不会在一开始找到空字符串后停止。它找到一个后面没有数字的“1”。这是第一场比赛。然后它在匹配后继续搜索。它找到一个空字符串并也匹配它,因为它等于零数字。

对于 RegEx,字符串“1”看起来像这样:

"" + "1" + ""

前两个单元(空字符串和“1”)匹配模式,第三个空字符串也匹配。

关于此的深入文章:http://www.regular-expressions.info/zerolength.html

My question is how come >6 < is present is the output when the string indexing is till index 5 ?

该行为是由于您的正则表达式,即 \d* 匹配 0 或更多数字。

如您所见,当开头没有数字时,它也会显示起始位置 0

同样,6last index +1,因为在最后一个字符之后也有一个空匹配项。

您应该使用 \d+ 作为正则表达式。