创建自定义jQuery过滤器

时间:2011-04-06 23:27:11

标签: javascript jquery regex

我刚刚了解到,您可以非常轻松地为jquery创建自定义过滤器,并将过滤器放在一起,以便对文本内容或任何属性使用正则表达式匹配功能。

我将该属性与正常的正则表达式相匹配,我知道这很奇怪,请不要被这个抛出,或者少考虑我。

我遇到的问题是正则表达式中的括号是否匹配。有时它很好,有时它会导致语法错误。

罚款::match(src/jquery.+\.(js)/i)') 错误::match(src/jquery.+\.js()/i)')

有人可以通过此代码告诉我这种行为的原因吗?

// create new jquery filter
jQuery.expr[':'].match = function(e,i,p) { // element, index, params

    // split params by custom format
    m = p[3].match(/^([a-z]*)(\/?)(.+)\2([a-z]*)$/)

    // set the attribute to be checked
    myAttr = m[1] ? m[1] : 'text'

    // define regex, including switches
    myRegExp = new RegExp(m[3],m[4]);

    // check for and return matched elements
    if(myAttr == 'text')
        return $(e).text().match(myRegExp)
    else
        return $(e).attr(myAttr) ? $(e).attr(myAttr).match(myRegExp) : false
};

// used like this
// :match(attr/regex/switches)
// or with default match (text) and case insensitivity switch (i):
// :match(/HeLlO WoRl/i)
// or in simplest form
// :match(RegexPattern)

// alert how many jquery plugins of the form jquery.something.js
alert($('script:match(src/jquery.+\.js/i)').length)

由于我收到了这个问题的优秀答案,我决定将我的过滤器重新设置为一个名为match的插件函数。有没有人对如何改进有任何意见?它适用于所有情况吗?

// will save as file called jquery.match.js
// will wrap with
// (function($){
$.fn.match = function(regex, attr){ // optional attr
    return this.filter(function(){
        var subject = attr ? $(this).attr(attr) : $(this).text()
        return subject && subject.match(regex) ? 1 : 0
    })
}
// and end with
// })

// used like this: $('body *').match(/some content/)
// or to match attributes like this: $('script').match(/jquery/i,'src')

1 个答案:

答案 0 :(得分:1)

由于第二个正则表达式中的额外括号,您的代码似乎失败了。由于jQuery正在解析表达式,并且不了解您的预定义格式,因此它会将:match(src/jquery.+\.js()/i)视为:match(src/jquery.+\.js() + /i)。请注意,第二个括号被解释为接近匹配。

可能有一种方法可以告诉jQuery接受)的转义版本,但我不确定如何。

替代地

你可以像这样使用jQuery filter函数。

$('script').filter( function(){
    return $(this).attr("src").match( /jquery/i ); 
});

要实现与插件提供的类似的通用性,您可以创建更高阶的功能来完成这项工作。

function createFilterFunction(regex, /*optional*/ attr){
    return function(){
        if( !attr ){
            return $(this).text().match(myRegex);
        }
        return $(this).attr(attr) ? $(this).attr(attr).match(regex) : false;
    };
}

然后你可以这样使用它:

var isJquery = createFilterFunction( /jquery.+\.js()/i, "src" );
alert( $('script').filter( isJquery ).length );

旁注

编写javascript时,如果在变量前没有包含var,它们将“泄漏”到全局命名空间中。因此,使用您的脚本的所有人都可以看到您的变量mmyAttrmyRegExp,更重要的是,它会更改m,{{{{{ 1}}和myAttr如果存在的话。将它们声明为myRegExp