Регулярное выражение для разбора номера версии - PullRequest
69 голосов
/ 17 сентября 2008

У меня есть номер версии следующей формы:

version.release.modification

где версия, выпуск и модификация являются либо набором цифр, либо символом подстановки '*'. Кроме того, любое из этих чисел (и любое предыдущее) может отсутствовать.

Таким образом, следующие значения действительны и разбираются как:

1.23.456 = version 1, release 23, modification 456
1.23     = version 1, release 23, any modification
1.23.*   = version 1, release 23, any modification
1.*      = version 1, any release, any modification
1        = version 1, any release, any modification
*        = any version, any release, any modification

Но они не действительны:

*.12
*123.1
12*
12.*.34

Может ли кто-нибудь предоставить мне не слишком сложное регулярное выражение для проверки и получения номеров выпуска, версии и модификации?

Ответы [ 19 ]

3 голосов
/ 17 сентября 2008
^(?:(\d+)\.)?(?:(\d+)\.)?(\*|\d+)$

Возможно, более кратким может быть:

^(?:(\d+)\.){0,2}(\*|\d+)$

Это может быть улучшено до 1.2.3.4.5. * Или ограничено точно X.Y.Z с использованием * или {2} вместо {0,2}

3 голосов
/ 17 сентября 2008

Еще одна попытка:

^(((\d+)\.)?(\d+)\.)?(\d+|\*)$

Это дает три части в группах 4,5,6 НО: Они выровнены вправо. Таким образом, первое ненулевое значение из 4,5 или 6 дает поле версии.

  • 1.2.3 дает 1,2,3
  • 1,2. * Дает 1,2, *
  • 1,2 дает ноль, 1,2
  • *** дает ноль, ноль, *
  • 1. * дает ноль, 1, *
2 голосов
/ 20 мая 2017

В качестве хорошего упражнения я могу принять это - vparse , который имеет крошечный источник , с простой функцией:

function parseVersion(v) {
    var m = v.match(/\d*\.|\d+/g) || [];
    v = {
        major: +m[0] || 0,
        minor: +m[1] || 0,
        patch: +m[2] || 0,
        build: +m[3] || 0
    };
    v.isEmpty = !v.major && !v.minor && !v.patch && !v.build;
    v.parsed = [v.major, v.minor, v.patch, v.build];
    v.text = v.parsed.join('.');
    return v;
}
2 голосов
/ 28 декабря 2016

Указание элементов XSD:

<xs:simpleType>
    <xs:restriction base="xs:string">
        <xs:pattern value="[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(\..*)?"/>
    </xs:restriction>
</xs:simpleType>
2 голосов
/ 17 сентября 2008

Имейте в виду, что регулярные выражения являются жадными, поэтому, если вы просто ищете в строке номера версии, а не в большем тексте, используйте ^ и $, чтобы отметить начало и конец вашей строки. Регулярное выражение от Грега, кажется, работает нормально (просто быстро попробовал в моем редакторе), но в зависимости от вашей библиотеки / языка первая часть все равно может соответствовать «*» в неправильных номерах версий. Может быть, я что-то упустил, так как я не использовал Regexp в течение года или около того.

Это должно гарантировать, что вы можете найти только правильные номера версий:

^ (\ * |..? \ D + (\ \ d +) * (\ \ *)) $

edit: на самом деле greg уже добавил их и даже улучшил свое решение, я слишком медлителен:)

2 голосов
/ 17 сентября 2008
(?ms)^((?:\d+(?!\.\*)\.)+)(\d+)?(\.\*)?$|^(\d+)\.\*$|^(\*|\d+)$

Точно совпадает с вашими 6 первыми примерами и отклоняет 4 других

  • группа 1: Major или Major.minor или '*'
  • группа 2, если существует: несовершеннолетний или *
  • группа 3, если существует: *

Вы можете удалить '(? Ms)'
Я использовал его, чтобы указать, что это регулярное выражение должно применяться к многострочным текстам через QuickRex

2 голосов
/ 17 сентября 2008

Это соответствует 1.2.3. * Тоже

^ (* |..? \ D + (\ d +) {0,2} (*)) $

Я бы предложил менее элегантный:

(* | \ d + (\ d +) (*).?.?) |.. \ D + \ d + \ d +)

2 голосов
/ 17 сентября 2008

Кажется довольно сложным иметь регулярное выражение, которое делает именно то, что вы хотите (т.е. принимаете только те случаи, которые вам нужны, и отклоняете все другие и возвращают некоторые группы для трех компонентов ). Я попробую и придумаю это:

^(\*|(\d+(\.(\d+(\.(\d+|\*))?|\*))?))$

IMO (я не тестировал всесторонне), это прекрасно работает как валидатор для ввода, но проблема в том, что это регулярное выражение не предлагает способ получения компонентов. Для этого вам все еще нужно разделить точку.

Это решение не все-в-одном, но в большинстве случаев в программировании оно не требуется. Конечно, это зависит от других ограничений, которые вы можете иметь в своем коде.

1 голос
/ 06 сентября 2016

Еще одно решение:

^[1-9][\d]*(.[1-9][\d]*)*(.\*)?|\*$
...