.test中的.test无法按预期工作

时间:2014-12-29 18:49:42

标签: javascript jquery html regex

我创建了一个自定义选择菜单的小插件。我必须在该下拉列表中实现搜索功能。但是我添加了功能,但有时它没有给出正确的结果。如果你输入' a'在输入框中,它应显示如下所示的结果

enter image description here

但是我的插件会在下面给出结果。它还用小写替换大写字母。 我试图解决这个问题,但无法解决这个问题。 fiddle

enter image description here

searchItem: function () {
    var patt = new RegExp(this.value, 'gi')
    var val = this.value;
    $('#options li').each(function () {

        if (!patt.test($(this).text())) {
            $(this).hide();
        } else {
            $(this).show();
            apply.highlight.call(this, val);
        }
    });

    $('#options h2').each(function () {
        if (!patt.test($('label', this).text())) {
            $(this).hide();
        } else {
            $(this).show();
            apply.highlight.call(this, val)
        }
    });

}

3 个答案:

答案 0 :(得分:2)

不匹配项的问题在于您对多个元素使用相同RegExp对象的测试方法。

但是.test()会移动每个匹配的起始位置(它用于匹配同一字符串上的后续匹配

因此,您应该为每个元素创建一个新的RegExp对象。 (或使用.match()并检查其长度

searchItem: function () {
        var pattValue = this.value;
        var val = this.value;
        $('#options li').each(function () {
            var patt = new RegExp(pattValue, 'gi');
            if (!patt.test($(this).text())) {
                $(this).hide();
            } else {
                $(this).show();
                apply.highlight.call(this, val);
            }
        });

        $('#options h2').each(function () {
            var patt = new RegExp(pattValue, 'gi');
            if (!patt.test($('label', this).text())) {
                $(this).hide();
            } else {
                $(this).show();
                apply.highlight.call(this, val);
            }
        });
    }

为了将chars替换为您输入的字符而不是用户提交的字符,您需要在RegExp中创建一个组并使用该捕获来替换匹配

    highlight: function (val) {
        var nn = new RegExp('(' + (val||'^$') + ')', 'gi');
        var txt = $(this).find('label').text();
        txt = txt.replace(nn, "<span class='highlight'>$1</span>");
        $('label', this).html(txt)
    }

最后,您需要在创建选项时重置li变量

演示 http://jsfiddle.net/b0rspd5e/

答案 1 :(得分:1)

这解决了问题的一部分(小写的一个加上无用的高光跨度)FIDDLE

highlight: function (val) {
    var nn = new RegExp('(' + val + ')', 'gi'),
         txt = $(this).find('label').text();
    if (val.replace(/\s/g, '') == '') {
        txt = txt.replace(new RegExp("<span class='highlight'>([\s\S]*?)</span>"),'$1');
        $('label', this).html(txt);
    }
    else{
    txt = txt.replace(nn, "<span class='highlight'>" + '$1' + "</span>");
    $('label', this).html(txt)
    }
}

基本上我已将()添加到regex以捕获该群组,然后'$1'替换匹配的值。

修改
FIDDLE VERSION 2
还完成了另一个问题(Gaby aka G. Petrioli建议的match方式),由于返回值,我花了一段时间。
基本上如果字符串没有返回任何匹配varnull,那么if(nMatch)就足够了。
如果true不是varnullundefinedNaNempty string ("")或{{1},则会返回0 }}

false

答案 2 :(得分:1)

您在使用g标志创建的同一正则表达式上反复调用.test方法。当您这样做时,后续的.test会继续lastIndex。以下是字符串a的匹配过程:

lastIndex    String              Substring to match    test() returns    Position
---------    ----------------    ------------------    --------------    --------
        0    " Volvo"            " Volvo"              false
        0    " Saab"             " Saab"               true                     2
        3    " Volvo"            "lvo"                 false
        0    " Saab"             " Saab"               true                     2
        3    " Mercedes"         "rcedes"              false
        0    " Audi"             " Audi"               true                     1
        2    " All Resident"     "ll Resident"         false
        0    " All Comercial"    " All Comercial"      true                     1

这解释了为什么“All Resident”标题未显示。解决方案是删除g标志,因为您只想测试每个字符串一次。