Java регулярное выражение викторина - PullRequest
0 голосов
/ 22 сентября 2018

Действительно трудно понять мир регулярных выражений.

Кто-нибудь может объяснить, как регулярное выражение делает результат, например,

, если n равно 1, результат будет 23020, n равен 2-> 33, n равно 3 -> 2103, 4 -> 32

    public static void main(String[] args) {
    String s = "some023020 num ber 033 02103 32 meh peh beh 4328";
}

    static String nthNumber(String s, int n) {
      Pattern pattern = Pattern.compile(
        "\\D*(?:\\d+\\D+){" + (n-1) + "}0*(\\d+).*");

      Matcher matcher = pattern.matcher(s);
      matcher.matches();
      return matcher.group(1);
    }

1 Ответ

0 голосов
/ 22 сентября 2018

Рассмотрим 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.

Надеюсь, это поможет!Лучшее, что нужно сделать, когда вы потерялись (не обязательно в регулярных выражениях), это посмотреть официальную документацию.Прочитайте это полностью, а не только чистя шпаргалку.Таким образом, вы получите лучшее понимание.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...