web-dev-qa-db-ja.com

Matcher.find()の仕組み

MatcherとPatternクラスの小さなスタブをテストしています...次の小さなスタブを参照してください。

package scjp2.escape.sequence.examples;

import Java.util.regex.Matcher;
import Java.util.regex.Pattern;

public class Sample_19 {

    public static void main(String a[]){
        String stream = "ab34ef";
        Pattern pattern = Pattern.compile("\\d*");

        //HERE * IS GREEDY QUANTIFIER THAT LOOKS FOR ZERO TO MANY COMBINATION THAT 
        //START WITH NUMBER 
        Matcher matcher = pattern.matcher(stream);

        while(matcher.find()){
            System.out.print(matcher.start()+matcher.group());
        }
    }

}

ここで...比較している文字列は "ab34ef"です。長さは6です。

いや繰り返しを見てみましょう...


イテレーションNO matcher.start()matcher.group()

1 0 ""

2 1 ""

3 2 34

4 4 ""

5 5 ""

ここで..let Combine ... matcher.start()+ matcher.group()....計算による出力は0123445です。

ただし、スタブは01234456を生成します。

「6」がどこから来るのか理解できません。文字列インデックスはゼロから始まるので、ここで最大インデックスは5になる可能性があります。

ループを6回繰り返します。なにか提案を ?

16
Gunjan Shah

正規表現はゼロ文字に一致できます。最終一致は、文字列の最後に発生するゼロ幅の文字列で、インデックス5の文字のafterです。したがって、このゼロ幅の文字列のインデックスは6。


余談ですが、セパレータを使用して出力を読みやすくすると、何が起こっているのかを理解しやすくなる場合もあります。

System.out.println(matcher.start()+ ": " + matcher.group());

結果:

0: 
1: 
2: 34
4: 
5: 
6: 

ideone

15
Mark Byers

式では*を使用します。これは0以上の数字を意味するため、どの数字にも一致しません。

この方法で正規表現を変更する

Pattern pattern = Pattern.compile("\\d+");

+の使用は、1以上を意味します。

9
dash1e