После обновления вопрос стал довольно сложным.Так как некоторые части регулярного выражения используются многократно, я взял на себя смелость проработать это в Ruby и впоследствии очистил его.Я покажу вам процесс сборки, чтобы можно было понять регулярное выражение.Ruby использует #{variable}
для регулярного выражения и интерполяции строк.
integer = /[1-9][0-9]*/
integer_or_range = /#{integer}(?: *- *#{integer})?/
integers_or_ranges = /#{integer_or_range}(?: +#{integer_or_range})*/
ending = /#{integer} *-/
regex = /^(?:#{integers_or_ranges}(?: +#{ending})?|#{ending})$/
#=> /^(?:(?-mix:(?-mix:(?-mix:[1-9][0-9]*)(?: *- *(?-mix:[1-9][0-9]*))?)(?: +(?-mix:(?-mix:[1-9][0-9]*)(?: *- *(?-mix:[1-9][0-9]*))?))*)(?: +(?-mix:(?-mix:[1-9][0-9]*) *-))?|(?-mix:(?-mix:[1-9][0-9]*) *-))$/
Очистка вышеприведенных листьев регулярного выражения:
^(?:[1-9][0-9]*(?: *- *[1-9][0-9]*)?(?: +[1-9][0-9]*(?: *- *[1-9][0-9]*)?)*(?: +[1-9][0-9]* *-)?|[1-9][0-9]* *-)$
Вы можете заменить [0-9]
на \d
, если хотите,но так как вы использовали синтаксис [0-9]
в своем вопросе, я использовал его и для ответа.Имейте в виду, что если вы замените [0-9]
на \d
, вам придется избежать обратной косой черты в строковом контексте.например."[0-9]"
равно "\\d"
Вы упоминаете в своем вопросе, что
Любой из вышеупомянутых форматов может иметь пробелы между ними.
Я предположил, что это означает, что пробелы (и) не допускаются до или после фактического содержимого, только между целыми числами и -
.
Действительный:
15 - 10
1234 -
Недействительно:
15 - 10
123
Если это не так, просто добавьте *
в начало и конец.
^ *... *$
Где ...
- остаток регулярного выражения.
Вы можете протестировать регулярное выражение в моей демонстрации , но из процесса сборки должно быть ясно, что делает регулярное выражение.
var
inputs = [
'1-5-10',
'1 - 5 - 10',
'1 - - 5',
'-5',
'15-10',
'15 - 10',
'15 - 10',
'1510',
'1510-',
'1510 -',
'1510 ',
' 1510',
' 15 - 10',
'10 20 - 30',
'10 20-30',
'100-150 200-250 300-',
'100-150 200-250 300- ',
'1-2526-27-28-',
'1-25 26-2728-',
'1-25 26-27 28-',
],
regex = /^(?:[1-9][0-9]*(?: *- *[1-9][0-9]*)?(?: +[1-9][0-9]*(?: *- *[1-9][0-9]*)?)*(?: +[1-9][0-9]* *-)?|[1-9][0-9]* *-)$/,
logInputAndMatch = input => {
console.log(`input: "${input}"`);
console.log(input.match(regex))
};
inputs.forEach(logInputAndMatch);