2

我有一个使用数据表显示的表,在每列上方我有一个空的文本表单字段,用户可以输入要过滤的术语。这适用于所有文本字段,也适用于整数字段。我正在对某些术语进行一些转换,例如如果用户输入 NULL 或 NOT NULL,例如我将其转换为正则表达式 ^$ 或 .

我知道正则表达式旨在搜索文本字符串,但这是数据表使用的,所以这就是我这样做的原因。我想要的是让用户能够输入诸如“x to y”之类的值并能够将其转换为正则表达式。我找不到这样做的功能,如果有人知道,请告诉我。

假设一个函数不存在,假设只搜索正整数,最多 7 个数字。因此可以搜索 0 - 9,999,999。此外,触发此操作的唯一方法是使用带有空格“to”的关键字 to。

所以像这样开始:

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; 
};

这适用于数字 0-9,但对此进行扩展似乎会变得非常难看。我愿意接受任何想法。谢谢。

4

2 回答 2

5

使用正则表达式验证一个数字是否在一个数字范围内是一个棘手的问题。这些正则表达式将匹配给定范围内的数字:

\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

当您有复杂的范围时,它开始失控

\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

在此处输入图像描述

于 2013-07-11T22:50:41.470 回答
0

向前

3 年后,我重新发现了这个问题,并有一些时间来解决这个难题。我并不完全清楚您为什么要使用正则表达式,但我确信这与提高数据库返回性能有关,因为它不会将所有可能的结果强加给将对其进行评估的客户端。

也就是说,我相信你有你的理由。

解释

这组函数将构造一个正则表达式,它将执行以下操作:

  • 验证给定的数字是否在给定的正整数范围之间
  • 拒绝超出该范围的数字
  • 要求整个字符串是数字
  • 适用于任何尺寸的数字
  • 允许整个范围包括较低和较高的数字

总体概述

该功能funRegexRange完成所有繁重的工作。通过构建一个匹配所有数字的0字符串UpperRange

然后,该函数funBuildRegexForRange使用负前瞻和正前瞻构造实际的正则表达式。

然后,生成的正则表达式将验证您的号码是否介于两者之间0,而UpperRange不是介于两者之间。0LowerRange

这些函数将允许数字或字符串值,但不验证输入是否为整数。提供不等于整数的值将产生不可预测的结果。

例子

要获取 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 + "'")
    }
}
于 2016-04-30T18:28:21.413 回答