このコードブロックを理解しようとしています。最初のもので、私たちが表現で探しているのは何ですか?
私の理解するところでは、それは任意の文字(0回以上*)とそれに続く0から9までの任意の数(1回以上+)とそれに続く任意の文字(0回以上*)です。
これが実行されると、結果は次のようになります。
Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT300
Found value: 0
誰かが私と一緒にこれを通過してもらえますか?
キャプチャグループを使用する利点は何ですか?
import Java.util.regex.Matcher;
import Java.util.regex.Pattern;
public class RegexTut3 {
public static void main(String args[]) {
String line = "This order was placed for QT3000! OK?";
String pattern = "(.*)(\\d+)(.*)";
// Create a Pattern object
Pattern r = Pattern.compile(pattern);
// Now create matcher object.
Matcher m = r.matcher(line);
if (m.find()) {
System.out.println("Found value: " + m.group(0));
System.out.println("Found value: " + m.group(1));
System.out.println("Found value: " + m.group(2));
} else {
System.out.println("NO MATCH");
}
}
}
あなたが抱えている問題は数量詞の種類にあります。最初のグループで greedy 数量詞を使用しています(index 1 - index 0はPattern
全体を表します)。可能な限り一致します(また、any文字なので、順序どおりにの文字数に一致します。次のグループの条件を満たすために)。
つまり、最初のグループ.*
は、次のグループ\\d+
が何か(この場合は最後の桁)に一致する限り、何にでも一致します。
第3グループに従って、それは最後のディジットの後で何でも一致します。
最初のグループでそれを消極的な数量詞に変更すると、期待通りの結果が得られます。つまり、3000です。part.
1番目のグループの疑問符に注意してください。
String line = "This order was placed for QT3000! OK?";
Pattern pattern = Pattern.compile("(.*?)(\\d+)(.*)");
Matcher matcher = pattern.matcher(line);
while (matcher.find()) {
System.out.println("group 1: " + matcher.group(1));
System.out.println("group 2: " + matcher.group(2));
System.out.println("group 3: " + matcher.group(3));
}
出力:
group 1: This order was placed for QT
group 2: 3000
group 3: ! OK?
JavaのPattern
に関する詳しい情報はこちら 。
最後に、キャプチャグループは角括弧で区切られており、あなたのPattern
が入力にマッチしたら、(とりわけ)後方参照を使うのにとても便利な方法を提供します。
Java 6では、グループはそれらの順序によってのみ参照することができます(入れ子になったグループと順序の微妙さに注意してください)。
Java 7では、名前付きグループを使用できるため、はるかに簡単です。
これはまったく問題ありません。
m.group(0)
)は常にあなたの正規表現でカバーされる領域全体を捉えます。この場合、それは文字列全体です。(.*)(\\d+)
(正規表現の最初の部分)は最初のグループの...QT300
intと2番目のグループの0
をカバーします。(.*)
を(.*?)
に変更してください。貪欲対怠惰の詳細については、このサイトをチェックしてください 。
ドキュメントから:
Capturing groups</a> are indexed from left
* to right, starting at one. Group zero denotes the entire pattern, so
* the expression m.group(0) is equivalent to m.group().
したがって、キャプチャグループ0は行全体を送信します。
あなたの理解は正しいです。しかし、私たちが通り抜けるならば:
(.*)
は文字列全体を飲み込みます。(\\d+)
が満足されるように文字を返す必要があります(これが0
が3000
ではなく捉えられる理由です)。(.*)
は残りを捉えます。しかし、その作者の本来の意図が何であったのかよくわかりません。