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

Javascript 正则表达式和字符串替换中难以捉摸的错误,javascript,regex,Javascript,Regex,我已经为一个页面编写了一个简单的javascript搜索程序,并且遇到了一些不匹配/错误匹配以及可能较差的css类匹配问题 如果我点击第一个示例“代码”(过滤到一个元素),然后点击“样式”链接,“代码”高亮度照明仍然存在。不用说,这是不可取的 我认为问题会发生在代码的过滤部分,但我觉得这一切都很好。特别是因为我抓取了标题的文本,而不是它的HTML,然后添加了一个新的跨度 function filter(searchTerm) { var searchPattern = new RegE

我已经为一个页面编写了一个简单的javascript搜索程序,并且遇到了一些不匹配/错误匹配以及可能较差的css类匹配问题

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

我认为问题会发生在代码的过滤部分,但我觉得这一切都很好。特别是因为我抓取了标题的文本,而不是它的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);
    });
}
函数过滤器(searchTerm){
var searchPattern=new RegExp(“(“+searchTerm+”),“ig”);//括号中添加了一个捕获组
条目。淡出(150,函数(){
noResults.hide();
$('header',this).each(函数(){
$(this.parent().hide();
//清除以前搜索的结果
$('li',this.removeClass('searchMatchTag');
//检查标题
$('h1',this).each(函数(){
var textToCheck=$('a',this).text();
if(textToCheck.match(searchPattern)){
textToCheck=textToCheck.replace(searchPattern,$1');//使用捕获组($1),以使替换匹配案例,并且不会得到奇怪的大写字母
$('a',this.html(textToCheck);
$(this).closest('.workshopentry').show();
}
});
//检查标签
$('li',this).each(函数(){
if($(this).text().match(searchPattern)){
$(this.addClass('searchMatchTag');
$(this).closest('.workshopentry').show();
}
});
});
如果($('.workshopentry[style*=“block”]')。长度==0){
noResults.show();
}
法代因(150);
});
}

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

在不转义searchTerm的情况下生成searchPattern可能是个问题。
*
的搜索项可以匹配任何内容

不如改用
var match=textToCheck.indexOf(searchTerm)>=0


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

如果不进行正确的引用,就不能使用正则表达式信任用户输入。考虑使用这样的报价函数:

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


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

结果是我缺少了一个删除先前匹配标记的检查

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);
}
var textToCheck=$('a',this).text();
if(textToCheck.match(searchPattern)){
//使用capture group($1),以使替换件与案例匹配,并且您不会得到奇怪的头饰
textToCheck=textToCheck.replace(搜索模式,$1');
$('a',this.html(textToCheck);
$(this).closest('.workshopentry').show();
}否则{
$('a',this.html(textToCheck);
}

如果您使用
$&
作为替换,那么您根本不需要捕捉括号。@Tomalak:Yikes,我总是忘记这一点。修正了。@Tim Good注释仍然是可编辑的:)-Jack,搜索单个模式时不需要捕获组<代码>新RegExp(重新格式化,'ig')足够了。@TimPietzcker谢谢你的提示:)@Tomalak没错!我花了一点时间才意识到
$&
可以应用两次:)