正则表达式和字符串替换中的难以捉摸的错误

时间:2012-11-21 04:51:17

标签: javascript regex

我为一个页面编写了一个简单的javascript搜索器,并且遇到了一些错配/错误匹配以及可能很差的css类匹配的问题。

http://jsfiddle.net/C4q7T/

如果我点击第一个示例'代码'(过滤到一个元素),然后在'样式'链接上,'代码'高光照仍然存在。不用说这是不可取的。

我认为问题会发生在代码的过滤部分,但这对我来说都很好看。特别是因为我正在抓取标题的文本而不是它的HTML,然后添加一个新的范围。

function filter(searchTerm) {
    var searchPattern = new RegExp('(' + searchTerm + ')', 'ig');  // The brackets add a capture group

    entries.fadeOut(150, function () {
        noResults.hide();

        $('header', this).each(function () {
            $(this).parent().hide();

            // Clear results of previous search
            $('li', this).removeClass('searchMatchTag');

            // Check the title
            $('h1', this).each(function () {
                var textToCheck = $('a', this).text();
                if (textToCheck.match(searchPattern)) {
                    textToCheck = textToCheck.replace(searchPattern, '<span class="searchMatchTitle">$1</span>');  //capture group ($1) used so that the replacement matches the case and you don't get weird capitolisations
                    $('a', this).html(textToCheck);
                    $(this).closest('.workshopentry').show();
                }
            });

            // Check the tags
            $('li', this).each(function () {
                if ($(this).text().match(searchPattern)) {
                    $(this).addClass('searchMatchTag');
                    $(this).closest('.workshopentry').show();
                }
            });
        });

        if ($('.workshopentry[style*="block"]').length === 0) {
            noResults.show();
        }

        entries.fadeIn(150);
    });
}

其他一些组合会让这种情况发生,但其他一些组合却没有,这使我很难找到导致此特定问题的原因。

3 个答案:

答案 0 :(得分:4)

如果没有正确引用,您无法信任使用正则表达式的用户输入。考虑使用这样的引用函数:

var rePattern = searchTerm.replace(/[.?*+^$\[\]\\(){}|]/g, "\\$&"),
searchPattern = new RegExp('(' + rePattern + ')', 'ig');  // The brackets add a capture group

修改

正如评论中所提到的,为什么捕获括号被用于执行搜索尚不清楚;您可以使用$&作为替换模式。当然,如果你简化了这篇文章的正则表达式,我会理解:)

答案 1 :(得分:1)

生成searchPattern而不转义searchTerm可能是个问题。 .*的searchTerm会匹配任何内容。

如何使用var match = textToCheck.indexOf(searchTerm) >= 0呢?

这将返回文本中子字符串searchTerm的第一个实例的索引,否则返回-1。

答案 2 :(得分:0)

结果我错过了检查以删除以前匹配的标签。

var textToCheck = $('a', this).text();
if (textToCheck.match(searchPattern)) {
    //capture group ($1) used so that the replacement matches the case and you don't get weird capitolisations
    textToCheck = textToCheck.replace(searchPattern, '<span class="searchMatchTitle">$1</span>');
    $('a', this).html(textToCheck);
    $(this).closest('.workshopentry').show();
} else {
    $('a', this).html(textToCheck);
}