Регулярное выражение для сопоставления группы, за которой следует определенный символ - PullRequest
4 голосов
/ 02 июня 2019

Так что мне нужно сопоставить следующее:

1.2.
3.4.5.
5.6.7.10

((\d+)\.(\d+)\.((\d+)\.)*) хорошо подойдет для самой первой строки, но проблема в том, что может быть много строк: может быть одна или несколько.

\n появится, только если будет более одной строки.

В строковой версии я получаю это так: "1.2.\n3.4.5.\n1.2."

Так что моя проблема: если есть только одна строка, \n не обязательно должен быть в конце, но если есть более одной строки, \n должен быть в конце для каждой строки, кроме самой последней.

Ответы [ 4 ]

2 голосов
/ 02 июня 2019

Вы можете проверить наличие новой строки в конце, используя положительный прогноз (?=.*\n):

(?=.*\n)(\d+)\.(\d+)\.((\d+)\.)*

См. regex demo

Редактировать

Вы можете использовать чередование , чтобы либо совпадать, когда на следующей строке есть тот же шаблон, либо после, либо совпадать с шаблоном, если за ним не следует новая строка.

^(?:\d+\.\d+\.(?:\d+\.)*(?=.*\n\d+\.\d+\.)|\d+\.\d+\.(?:\d+\.)*(?!.*\n))

Regex demo

  • ^ Начало строки
  • (?: Группа без захвата
    • \d+\.\d+\.Совпадение 2 раза с цифрой и точкой
    • (?:\d+\.)* Повторите 0+ раз, совпадая с 1+ цифрами и точкой
    • (?=.*\n\d+\.\d+\.) Положительный прогноз, подтвердите, что следует за новой строкой, начинающейся с шаблона
    • | Или
    • \d+\.\d+\. Совпадение 2 раза с цифрой и точкой
    • (?:\d+\.)* Повторить 0+ раз, сопоставляя 1+ цифры и точку
    • *(?!.*\n) Отрицательный взгляд, утверждайте, что это не новая строка
  • ) Закрыть группу без захвата
2 голосов
/ 02 июня 2019

Вот образец, который я предлагаю:

^\d+(?:\.\d+)*\.?(?:\n\d+(?:\.\d+)*\.?)*$

Демо

Вот краткое объяснение шаблона:

^                   from the start of the string
\d+                 match a number
(?:\.\d+)*          followed by dot, and another number, zero or more times
\.?                 followed by an optional trailing dot
(?:\n               followed by a newline
\d+(?:\.\d+)*\.?)*  and another path sequence, zero or more times
$                   end of the string
0 голосов
/ 02 июня 2019

Большинство языков программирования предлагают флаг m.Это модификатор multiline .Включение этого параметра позволит $ совпадать в конце строк и в конце строки.

Приведенное ниже решение только добавляет $ к вашему текущему регулярному выражению и устанавливает флаг m.Это может варьироваться в зависимости от вашего языка программирования.

var text = "1.2.\n3.4.5.\n1.2.\n12.34.56.78.123.\nthis 1.2. shouldn't hit",
    regex = /((\d+)\.(\d+)\.((\d+)\.)*)$/gm,
    match;


while (match = regex.exec(text)) {
  console.log(match);
}

Вы можете упростить регулярное выражение до /(\d+\.){2,}$/gm, а затем разбить полное совпадение на основе символа точки, чтобы получить все различные числа.Ниже приведен пример JavaScript, но получение подстроки и разбиение строки - довольно простые операции в большинстве языков.

var text = "1.2.\n3.4.5.\n1.2.\n12.34.56.78.123.\nthis 1.2. shouldn't hit",
    regex = /(\d+\.){2,}$/gm;

/* Slice is used to drop the dot at the end, otherwise resulting in
 * an empty string on split.
 *
 *     "1.2.3.".split(".")   //=> ["1", "2", "3", ""]
 *     "1.2.3.".slice(0, -1) //=> "1.2.3"
 *     "1.2.3".split(".")    //=> ["1", "2", "3"]
 */
console.log(
  text.match(regex)
      .map(match => match.slice(0, -1).split("."))
);

Для получения дополнительной информации о флагах / модификаторах регулярных выражений смотрите: Справочник по регулярным выражениям: Модификаторы режима

0 голосов
/ 02 июня 2019

(\d+\.*)+\n* будет соответствовать тексту, который вы предоставили.Если вам нужно убедиться, что последняя строка также заканчивается на ., тогда (\d+\.)+\n* будет работать.

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