Рассмотрим n = 1. Тогда ваш шаблон станет:
\D*(?:\d+\D+){0}0*(\d+).*
Сначала вам нужно понять, что обозначают номера групп в matcher.group()
.Группа 0 содержит подстроку, соответствующую шаблону complete .
В вашем случае это целая строка.Почему?
\D*
- соответствует нулю или более [^ 0-9], т.е. всем символам, кроме 0-9.Таким образом, он будет соответствовать первым 4 буквам "некоторым" .
(?:\d+\D+){0}
- соответствует одному или нескольким из [0-9] и одному или нескольким из [^ 0-9].?:
в начале называется non capturing group
.В основном это означает, что не рассматривайте это как группу.{0} указывает , сколько раз (?:\d+\D+){0}
должно быть сопоставлено.Прямо сейчас это 0, поэтому ничего не соответствует.
0*
- Соответствует одному или нескольким 0. Так что это соответствует "0" после "some" ,Таким образом, мы соответствовали some0 до настоящего момента.
(\d+)
- Соответствует одному или нескольким из [0-9].Это соответствует "23020" .Посмотрите, как \ d + находится внутри ()
, и в начале у него нет ?:
.Это означает, что это будет наша группа 1. (и поэтому matcher.group (1) для n = 1 возвращает 23020).
.*
- соответствует нулю или более любого символа.Так что это соответствует до конца строки.
Так вот почему группа 0 содержит полную строку.
Теперь переходим к группе 1.
В нашем случае группа 1 - это (\d+)
- подстрока, содержащая один или несколько из [0-9].Но это не так. Часть строки, которая предшествует этой подстроке, также должна соответствовать шаблону \D*(?:\d+\D+){0}0*
.Это очень важно.
Итак, давайте быстро проанализируем вашу строку.
\D*
- соответствует "некоторые"
(?:\d+\D+){0}
- Совпадение нулевых вхождений (из-за {0}).Так что ничего не соответствует.
0*
- соответствует "0" .Итак, мы сопоставили "some0" .
(\d+)
- соответствует 23020 .
Это отвечает на первую часть вашего вопроса: почему n = 1, почему результат равен 23020 ?
Прежде чем мы продолжим, обратите внимание, что пробел такжесимвол, который соответствует \ D.Это звучит тривиально, но часто упускается из виду.
Теперь, когда n = 2, ваш шаблон становится:
\D*(?:\d+\D+){1}0*(\d+).*
Давайте быстро проанализируем его:
\D*
- совпадения "некоторые"
(?:\d+\D+){1}
- На этот раз нам нужно совпадать ровно с одним вхождением (?:\d+\D+)
.Таким образом, это будет "023020 номер"
0*
- соответствует 0. Таким образом, мы соответствовали "some023020 номер 0"
(\ d +) - соответствует 33 (а не 33 02103 32 из-за пробела).
Итак, когда n = 2, matcher.group (1) вернуть 33.
Таким же образом можно проанализировать n = 3,4.
Надеюсь, это поможет!Лучшее, что нужно сделать, когда вы потерялись (не обязательно в регулярных выражениях), это посмотреть официальную документацию.Прочитайте это полностью, а не только чистя шпаргалку.Таким образом, вы получите лучшее понимание.