独书先生 Menu

js实现 Excel通配符比较两个字符串

需求分析:

a 与 b比较(a和b可为字符串或数字),其中b的内容比较丰富,开头可含比较符(>, >=, <, <=, =),任意位置可含通配符(Excel规则:   ?  ~  ~?), 返回Boolean(true or false)

通配符规则:

?(问号)

任何一个字符
例如,sm?th 可找到“smith”和“smyth”
*(星号) 任意的数量字符
例如,*east 可找到“Northeast”和“Southeast”
~(波形符)后跟 ?、* 或 ~

问号、星号或波形符
例如,fy06~? 可找到“fy06?”

通配符的使用详细参照Excel官网

代码:

function acompareb(a,b){ //a 与 b比较,b可为含比较符,通配符 * ? ~* ~?,返回Boolean(true or false)

    var operatorjson = {
        "==":1, "!=":1, "<>":1, "<=":1,  ">=":1,  "=":1,  "+":1,  "-":1,  ">":1,  "<":1,  "/":1,  "*":1,  "%":1,  "&":1
    }
    function isWildcard(a,b){ //正则匹配通配符: * ? ~* ~?,a目标参数,b通配符
        a = a.toString();
        b = b.toString();

        if(isCompareOperator(b).flag){
            b = isCompareOperator(b).num;
        }
        var str = "";
        for(var i = 0;i < b.length;i++){
            var v = b.charAt(i);

            if(v == "*" ){
            str += ".*";
            }else if(v == "?"){
            str += ".";
            }else if(v == "~"){
            if(b.charAt(i+1) == "*"){
                str += "\\*";
                i++;
            }else if(b.charAt(i+1) == "?"){
                str += "\\?";
                i++;
            }else{
                str += "~";
            }
            }else{
            str += v;
            }

        }

        var reg = new RegExp("^" + str + "$","g");
        return !!a.match(reg);

    }

    function isCompareOperator(str){ //判断前一个或者两个字符是否是比较运算符
        str = str.toString();
        var ope = ""; //存放比较运算符
        var num = ""; //截取比较运算符之后的数字用于实际比较
        var strOne = str.substr(0,1); 
        var strTwo = str.substr(1,1);
        var flag = false;
        var ret;

        if(strOne == ">"){
            if(strTwo == "="){
                ope = str.substr(0,2);
                num = str.substr(2);
                flag = true;
            }else if(strTwo != "="){
                ope = str.substr(0,1);
                num = str.substr(1);
                flag = true;
            }
        }else if(strOne == "<"){
            if(strTwo == "=" || strTwo == ">"){
                ope = str.substr(0,2);
                num = str.substr(2);
                flag = true;
            }else if(strTwo != "=" && strTwo != ">"){
                ope = str.substr(0,1);
                num = str.substr(1);
                flag = true;
            }
        }else if(strOne == "=" && strTwo != "="){
            ope = str.substr(0,1);
            num = str.substr(1);
            flag = true;
        }
        ret = {"flag":flag,"ope":ope,"num":num};
        return ret;
    }

    function compareWith(){
        //函数功能:比较或运算 第一个参数和第三个参数,返回比较结果的布尔值或者运算值
        //operatorjson; 存储运算符和比较符
        var args = arguments;

        var fp = args[0]; //参数一
        var sp = args[1]; //操作符
        var tp = args[2]; //参数二 

        var function_str = "";
            if(sp in operatorjson){
                //处理第一个或者第三个参数带操作符 例:="<>" & 75
                if(fp in operatorjson || tp in operatorjson){
                    if(sp == "&"){
                        sp = "+";
                    }
                    function_str =eval("'" + fp + "'" + sp + "'" + tp + "'");
                    return function_str;
                }

                if(sp == "<>"){sp = "!=";}
                if(sp == "="){sp = "==";}
                if(!isNaN(parseFloat(fp)) && !isNaN(parseFloat(tp))){
                    if(sp == "&"){
                        sp = "+";
                        function_str ="'" + fp + "'" + sp + "'" + tp + "'" ;

                    }else{ 
                        fp = parseFloat(fp);
                        tp = parseFloat(tp);
                        function_str = fp + sp + tp;  
                    } 
                } 
                else{
                    if(sp == "&"){
                        sp = "+";
                    }
                    function_str ="'" + fp + "'" + sp + "'" + tp + "'" ;
                } 

            }

        function_str = eval(function_str);  //执行成为True or False or 运算符结果
        return function_str;

    }

    var flag = false;
    if(a == b){
        return true;
    }
    if(!isNaN(parseFloat(b))){
        b = parseFloat(b);
        flag = compareWith(a,"==",b);
    }else if(typeof(b) == "string"){ //条件输入字符串,如:">233"

        if(b.indexOf("*") != -1 || b.indexOf("?") != -1){ // 正则匹配:输入通配符:"黑*","白?",以及"白?黑*~*"
            //通配符函数
            return isWildcard(a,b);
        }else if(isCompareOperator(b).flag){ //"黑糖"
            var ope = isCompareOperator(b).ope;
            var num = isCompareOperator(b).num;
            flag = compareWith(a,ope,num);
        }else{
            flag = compareWith(a,"==",b);
        }
    }
    return flag;
}