[英]Convert human readable number range to Regex
I have a table that is displayed using datatables, above each column I have an empty text form field that users can type in terms to filter on. 我有一个使用数据表显示的表,在每一列的上方都有一个空的文本表单字段,用户可以根据其输入内容进行过滤。 This works fine on all text fields, and works ok on integer fields as well.
这在所有文本字段上都可以正常工作,在整数字段上也可以。 I am doing some conversion for some terms such as if the user types in NULL or NOT NULL for example I convert that to the regex ^$ or .
我正在对某些术语进行某种转换,例如,如果用户键入NULL或NOT NULL,则将其转换为regex ^ $或。
I know regex is intended to search text strings but this is what datatables uses so thats why I am doing this. 我知道正则表达式旨在搜索文本字符串,但这就是数据表所使用的,因此这就是我这样做的原因。 What I want is for users to be able to type in a value such as "x to y" and to be able to convert that to a regular expression.
我想要的是用户能够输入“ x to y”之类的值并将其转换为正则表达式。 I cannot find a function that does this, if anyone knows of one please let me know.
我找不到执行此操作的函数,如果有人知道一个函数,请告诉我。
Assuming a function doesn't already exist, assume that only positive integers will be searched, and say up to 7 digits. 假设尚不存在函数,则假设仅搜索正整数,并说最多7位数字。 so 0 - 9,999,999 can be searched.
因此可以搜索0-9,999,999。 Also the only way this is triggered is by the keyword to with spaces " to ".
同样,触发此方法的唯一方法是使用关键字to,使其带有空格“至”。
so something like this to start: 所以这样的事情开始:
function convertNumRangeRegex(s){
if(s.indexOf(" to ") != -1){
var range = s.split(" to ");
lowRange = Number(range[0]);
highRange = Number(range[1]);
if(lowRange >= 0 && lowRange < 10 && highRange < 10){
s = "^[" + lowRange + "-" + highRange + "]$";
}};
return s;
};
This works with numbers 0-9, but expanding on this seems like it would get pretty ugly. 这适用于数字0-9,但对此进行扩展似乎很难看。 I am up for any ides.
我支持任何想法。 Thanks.
谢谢。
Validating a number is in a range of numbers with regex is tricky problem. 使用正则表达式验证数字是否在数字范围内是一个棘手的问题。 These regexs will match a number within a given range:
这些正则表达式将匹配给定范围内的数字:
\b[0-9]{1,7}\b # 0-9999999
\b[1-9][0-9]{2,6}\b # 100-9999999
\b([4-9][0-9]{4}|[1-9][0-9]{5,6})\b # 40000-9999999
It starts to get out of hand when you have complex ranges 当您有复杂的范围时,它开始失控
\\b(?:5(?:4(?:3(?:2[1-9]|[3-9][0-9])|[4-9][0-9]{2})|[5-9][0-9]{3})|[6-9][0-9]{4}|[1-9][0-9]{5}|[1-8][0-9]{6}|9(?:[0-7][0-9]{5}|8(?:[0-6][0-9]{4}|7(?:[0-5][0-9]{3}|6(?:[0-4][0-9]{2}|5(?:[0-3][0-9]|4[0-3]))))))\\b # 54321-9876543
3 years later I rediscovered this question, and had some time to solve the puzzle. 3年后,我重新发现了这个问题,并花了一些时间解决这个难题。 I'm not entirely clear on why you'd want to use a regex, but I'm sure it has to do with improving database return performance by not forcing all possible results to the client where they'll be evaluated.
对于您为什么要使用正则表达式,我尚不完全清楚,但是我敢肯定,这与通过不将所有可能的结果强制提供给客户端进行评估来提高数据库的返回性能有关。
That said, I'm sure you have your reasons. 就是说,我确定您有您的理由。
This set of functions will construct a regular expression that will do the following: 这组函数将构造一个执行以下操作的正则表达式:
The function funRegexRange
does all the heavy lifting. 函数
funRegexRange
完成所有繁重的工作。 By building a string that will match all numbers from 0
to UpperRange
通过构建将匹配从
0
到UpperRange
所有数字的字符串
The function funBuildRegexForRange
then constructs the actual regex with a negative lookahead and a positive lookahead. 然后,函数
funBuildRegexForRange
构造具有负先行和正先行的实际正则表达式。
The resulting regex will then validate your number is between 0
and the UpperRange
inclusive, and not between 0
and the LowerRange
not inclusive. 然后,生成的正则表达式将验证您的数字是否介于
0
和UpperRange
之间(包括UpperRange
,而不是介于0
和LowerRange
之间(不包括LowerRange
。
The functions will allow either numbers or strings values, but does not validate the inputs are integers. 该函数将允许数字或字符串值,但不验证输入是否为整数。 Providing values which do not equate to integers will yield unpredictable results.
提供不等于整数的值将产生不可预测的结果。
To get the regex for a range from 400 to 500: 要获取介于400到500之间的正则表达式:
re = funBuildRegexForRange( 400, 500, true )
By setting the last parameter to true you it'll show the various parts being constructed and the full regex. 通过将最后一个参数设置为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})$)/
The resulting regex looks like 生成的正则表达式看起来像
Asking for a range between 400 - 999999999999 [twelve digits] returns this monster: 要求范围在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})$)/
Live Example: https://repl.it/CLd4/4 实时示例: https : //repl.it/CLd4/4
Full code: 完整代码:
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 + "'")
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.