Форвард
3 спустя годы я снова открыл этот вопрос и успел решить загадку. Я не совсем понимаю, почему вы хотите использовать регулярное выражение, но я уверен, что он связан с улучшением производительности базы данных, не вызывая все возможные результаты для клиента, где они будут оцениваться.
Это, я уверен, у вас есть свои причины.
Объяснение
Этот набор функций будет построить регулярное выражение, которое будет сделать следующее:
- проверить заданное число находится между заданном диапазоне положительных целых чисел
- отклоняет номера, которые вне этого диапазона
- требует, чтобы вся строка была цифрой
- работает с любыми числами
- позволяют весь диапазон включать нижние и верхние числа
Общий обзор
Функция funRegexRange
делает всю тяжелую работу.Построив строку, которая будет соответствовать всем цифрам от 0
до UpperRange
Функции funBuildRegexForRange
затем конструирует фактическое регулярное выражение с отрицательным предпросмотром и положительным предпросмотром.
В результате регулярных выражений будет проверять ваш номер находится между 0
и UpperRange
включительно, а не между 0
и LowerRange
не включительно.
Функции позволят либо цифры, либо значения строк, но не подтверждают, что входы являются целыми числами. Предоставление значений, не равных целым числам, даст непредсказуемые результаты.
Примеров
Чтобы получить регулярное выражение для диапазона от 400 до 500:
re = funBuildRegexForRange(400, 500, true)
Установив последний параметр, чтобы верно вам это продемонстрируют различные части строятся и полное регулярное выражение.
[0-3][0-9]{2}, [0-9]{1,2}
[0-4][0-9]{2}, 500, [0-9]{1,2}
Full Regex = /^(?!(?:[0-3][0-9]{2}|[0-9]{1,2})$)(?=(?:[0-4][0-9]{2}|500|[0-9]{1,2})$)/
В результате регулярное выражение выглядит
Просить диапазоне от 400 - 999999999999 [двенадцать цифр] возвращает этот монстр:
Full Regex = /^(?!(?:[0-3][0-9]{2}|[0-9]{1,2})$)(?=(?:[0-8][0-9]{11}|9[0-8][0-9]{10}|99[0-8][0-9]{9}|999[0-8][0-9]{8}|9999[0-8][0-9]{7}|99999[0-8][0-9]{6}|999999[0-8][0-9]{5}|9999999[0-8][0-9]{4}|99999999[0-8][0-9]{3}|999999999[0-8][0-9]{2}|9999999999[0-8][0-9]|99999999999[0-8]|999999999999|[0-9]{1,11})$)/
Javascript код
Живой пример: https://repl.it/CLd4/4
Полный код:
function funRegexRange (UpperRange, Inclusive, Debug) {
// this function will build a basic regex that will match a range of integers from 0 to UpperRange
UpperRange += "" // convert the value to a string
var ArrUpperRange = UpperRange.split("")
var intLength = ArrUpperRange.length
var LastNumber = ArrUpperRange[intLength]
var AllSubParts = []
var SubPortion = ""
for (i = 0; i < intLength; i++) {
Position = intLength - (i +1)
if (Position >= 2) {
Trailing = "[0-9]{" + Position + "}";
} else if (Position == 1) {
Trailing = "[0-9]";
} else {
Trailing = "";
}
if (ArrUpperRange[i] >= 2) {
ThisRange = "[0-" + (ArrUpperRange[i] - 1) + "]"
} else if (ArrUpperRange[i] == 1) {
ThisRange = "0"
} else {
ThisRange = ""
}
if (Debug) {
// console.log("Pos='" + Position + "' i='" + i + "' char='" + ArrUpperRange[i] + "' ThisRange='" + ThisRange + "' Trailing='" + Trailing + "'")
}
if (ThisRange === "" && Trailing !== "") {
// no need to return the this as this will be matched by the future SubPortions
} else {
if (Position === 0 && ThisRange ==="" && Trailing === "") {
} else {
AllSubParts.push(SubPortion + ThisRange + Trailing);
}
}
SubPortion += ArrUpperRange[i]
}
// insert the last number if this it should be included in the range
if (Inclusive) {
AllSubParts.push(UpperRange)
}
// all all numbers that have less digits than the range
if (intLength - 1 >= 2) {
Trailing = "[0-9]{1," + (intLength - 1) + "}";
} else if (intLength - 1 >= 1) {
Trailing = "[0-9]";
} else {
Trailing = "";
}
// insert trailing into the output stream
if (Trailing){
AllSubParts.push(Trailing);
}
if (Debug) {
console.log(AllSubParts.join(", "));
}
return AllSubParts.join("|");
} // end function funRegexRange
function funBuildRegexForRange (Start, End, Debug){
var Regex = new RegExp("^(?!(?:" + funRegexRange (LowerRange, false, Debug) + ")$)(?=(?:" + funRegexRange (UpperRange, true, Debug) + ")$)" ,"")
if (Debug) {
console.log("Full Regex = " + Regex + "")
}
return Regex
}
var Debug = false;
var Inclusive = true;
var LowerRange = "400";
var UpperRange = "500";
// var re = funBuildRegexForRange(LowerRange, UpperRange, true)
if (Debug){
for (Range = 0; Range < 13; Range++) {
console.log ("funRegexRange ('" + Range + "', " + Inclusive +") =");
funRegexRange (Range, Inclusive, Debug);
console.log ("");
}
}
var Regex = funBuildRegexForRange(LowerRange, UpperRange, Debug)
for (i = 1000; i < 1020; i++) {
TestNumber = i + ""
if (TestNumber.match(Regex)) {
console.log(TestNumber + " TestNumber='" + TestNumber + "' matches");
} else {
// console.log(TestNumber + " does not match '" + Regex + "'")
}
}
Если речь идет о базе данных, вы бы жир лучше обеспечить различные пути для согласования числа, согласования диапазона и т.д. Было бы получить довольно некрасиво действительно. Вместо того, чтобы возвращать регулярное выражение, возвращайте функцию обратного вызова, которая может возвращать true или false, en в зависимости от предоставленного условия поиска, что обратный вызов может использовать регулярное выражение, меньшее/большее сравнение, соответствие диапазонов и т. Д. – Wrikken
только что нашел этот вопрос, который похож на http : //stackoverflow.com/questions/4101053/generate-a-regexp-from-a-numeric-range Похоже, что не рекомендуется использовать регулярное выражение для интерпретации чисел –
@DavidStetler - Да, при попытке автоматического генерации этих регулярных выражений , без вопросов, с просьбой о боли. Во имя здравомыслия и порядочности просто преобразуйте строки в числа, используя 'parseInt', или что-то в этом роде. – femtoRgon