向前
3 年后,我重新发现了这个问题,并有一些时间来解决这个难题。我并不完全清楚您为什么要使用正则表达式,但我确信这与提高数据库返回性能有关,因为它不会将所有可能的结果强加给将对其进行评估的客户端。
也就是说,我相信你有你的理由。
解释
这组函数将构造一个正则表达式,它将执行以下操作:
- 验证给定的数字是否在给定的正整数范围之间
- 拒绝超出该范围的数字
- 要求整个字符串是数字
- 适用于任何尺寸的数字
- 允许整个范围包括较低和较高的数字
总体概述
该功能funRegexRange
完成所有繁重的工作。通过构建一个匹配所有数字的0
字符串UpperRange
然后,该函数funBuildRegexForRange
使用负前瞻和正前瞻构造实际的正则表达式。
然后,生成的正则表达式将验证您的号码是否介于两者之间0
,而UpperRange
不是介于两者之间。0
LowerRange
这些函数将允许数字或字符串值,但不验证输入是否为整数。提供不等于整数的值将产生不可预测的结果。
例子
要获取 400 到 500 范围内的正则表达式:
re = funBuildRegexForRange( 400, 500, true )
通过将最后一个参数设置为 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 + "'")
}
}