最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Javascript Regular Expressions with jQuery Contains Regex Extension - Stack Overflow

programmeradmin0浏览0评论

I'm using an extension for jQuery "contains", shown below:

$.extend($.expr[':'],{
    containsExact: function(a,i,m){
        return $.trim(a.innerHTML.toLowerCase()) === m[3].toLowerCase();
    },
    containsExactCase: function(a,i,m){
        return $.trim(a.innerHTML) === m[3];
    },
    containsRegex: function(a,i,m){
        var regreg =  /^\/((?:\\\/|[^\/])+)\/([mig]{0,3})$/,
        reg = regreg.exec(m[3]);
        return RegExp(reg[1], reg[2]).test($.trim(a.innerHTML));
    }
});

I have a table with certain cells that I'm trying to format conditionally, so I'm using the extension in a td selector, with the containsRegex function. The problem that I'm running into is that many of the regular expressions that I'm trying to use (which I've tested out on javascript regex testers like this and they've worked) do not work with this function. These are the various strings that I'd like to match:

Note that a "x" could be a x,t,f or v and an "X" could be an X,T,F or V. Lastly an "(mb)" could be any two lower case letters a-z in parenthesis.

-, (mb), x*, x*(mb), x, x(mb), X*, X*(mb), X

And here is the code with several of the regex statements that I'm using:

 $("td:containsExact('-')").addClass("0 queue"); // -
 $("td:containsRegex('/[^xtfv*]\([a-z]{2}\)/g')").addClass("1 active"); // (mb)
 $("td:containsRegex('/\b[xtfv]\*(?!\()/g')").addClass("2 queue review"); // x*
 $("td:containsRegex('/\b[xtfv]\*(?:\([a-z]{2}\))/g')").addClass("3 active review"); // x*(mb)
 $("td:containsRegEx('/\b[xtfv](?![*\(])/g')").addClass("4 queue");  // x
 $("td:containsRegEx('/\b[xtfv](?:\([a-z]{2}\))/g')").addClass("5 active");  // x(mb)
 $("td:containsRegEx('/\b[XTFV]\*(?!\()/g')").addClass("6 queue review");  // X*
 $("td:containsRegEx('/\b[XTFV]\*(?:\([a-z]{2}\))/g')").addClass("7 active review");  // X*(mb)
 $("td:containsRegEx('/\b[XTFV](?![*\(])/g')").addClass("8 done");  // X

Most of these pass errors in Chrome. Does anyone have any pointers? Is the contains extension limited somehow?

Thanks in advance for your help!

I'm using an extension for jQuery "contains", shown below:

$.extend($.expr[':'],{
    containsExact: function(a,i,m){
        return $.trim(a.innerHTML.toLowerCase()) === m[3].toLowerCase();
    },
    containsExactCase: function(a,i,m){
        return $.trim(a.innerHTML) === m[3];
    },
    containsRegex: function(a,i,m){
        var regreg =  /^\/((?:\\\/|[^\/])+)\/([mig]{0,3})$/,
        reg = regreg.exec(m[3]);
        return RegExp(reg[1], reg[2]).test($.trim(a.innerHTML));
    }
});

I have a table with certain cells that I'm trying to format conditionally, so I'm using the extension in a td selector, with the containsRegex function. The problem that I'm running into is that many of the regular expressions that I'm trying to use (which I've tested out on javascript regex testers like this and they've worked) do not work with this function. These are the various strings that I'd like to match:

Note that a "x" could be a x,t,f or v and an "X" could be an X,T,F or V. Lastly an "(mb)" could be any two lower case letters a-z in parenthesis.

-, (mb), x*, x*(mb), x, x(mb), X*, X*(mb), X

And here is the code with several of the regex statements that I'm using:

 $("td:containsExact('-')").addClass("0 queue"); // -
 $("td:containsRegex('/[^xtfv*]\([a-z]{2}\)/g')").addClass("1 active"); // (mb)
 $("td:containsRegex('/\b[xtfv]\*(?!\()/g')").addClass("2 queue review"); // x*
 $("td:containsRegex('/\b[xtfv]\*(?:\([a-z]{2}\))/g')").addClass("3 active review"); // x*(mb)
 $("td:containsRegEx('/\b[xtfv](?![*\(])/g')").addClass("4 queue");  // x
 $("td:containsRegEx('/\b[xtfv](?:\([a-z]{2}\))/g')").addClass("5 active");  // x(mb)
 $("td:containsRegEx('/\b[XTFV]\*(?!\()/g')").addClass("6 queue review");  // X*
 $("td:containsRegEx('/\b[XTFV]\*(?:\([a-z]{2}\))/g')").addClass("7 active review");  // X*(mb)
 $("td:containsRegEx('/\b[XTFV](?![*\(])/g')").addClass("8 done");  // X

Most of these pass errors in Chrome. Does anyone have any pointers? Is the contains extension limited somehow?

Thanks in advance for your help!

Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Jan 18, 2012 at 17:11 mbeasleymbeasley 4,8745 gold badges30 silver badges39 bronze badges 1
  • For reference: the error it passes is "Uncaught Syntax error, unrecognized expression: )/g')" on "x*" and "X*". It appropriately applies the class to "(mb)" but also applies those same classes for "x*(mb)"... The rest of the searches don't pass errors, but they also don't find matches. – mbeasley Commented Jan 18, 2012 at 18:54
Add a ment  | 

2 Answers 2

Reset to default 5

Ok, I think I got it... These are the changes I made:

  • The bottom five selectors have a capital "E" and should all be "containsRegex()"
  • I changed the containsRegex a tiny bit by adding a "reg" check in the return, to make it more sturdy:

    containsRegex: function(a,i,m){
      var regreg =  /^\/((?:\\\/|[^\/])+)\/([mig]{0,3})$/,
       reg = regreg.exec(m[3]);
      return reg ? RegExp(reg[1], reg[2]).test($.trim(a.innerHTML)) : false;
    }
    
  • All escaped characters in the regex need to be double escaped ( i.e. \( needs to be \\( )

  • I removed all the single quotes to actually help me from being distracted

  • I removed the class name numbers. I know ID's shouldn't start with numbers and I'm pretty sure class names shouldn't start or only be a number either. Anyway, this led to some selectors adding the same regex (i.e. "x" and "-" look the same, as well as "x*(mb)" and "X*(mb)" with the css in the demo).

Anyway, I'll update my gist with this code and your demo:

/* jQuery selector to match exact text inside an element
*  :containsExact()     - case insensitive
*  :containsExactCase() - case sensitive
*  :containsRegex()     - set by user ( use: $(el).find(':containsRegex(/(red|blue|yellow)/gi)') )
*/
$.extend($.expr[':'],{
  containsExact: function(a,i,m){
    return $.trim(a.innerHTML.toLowerCase()) === m[3].toLowerCase();
  },
  containsExactCase: function(a,i,m){
    return $.trim(a.innerHTML) === m[3];
  },
  containsRegex: function(a,i,m){
    var regreg =  /^\/((?:\\\/|[^\/])+)\/([mig]{0,3})$/,
    reg = regreg.exec(m[3]);
    return reg ? RegExp(reg[1], reg[2]).test($.trim(a.innerHTML)) : false;
  }
});

// -, (mb), x*, x*(mb), x, x(mb), X*, X*(mb), X

$("td:containsRegex(/^[xtfv]$/)").addClass("queue");  // x
$("td:containsRegex(/^[xtfv]\\*$/)").addClass("queue review"); // x*
$("td:containsRegex(/^\\([a-z]{2}\\)$/)").addClass("active"); // (mb)
$("td:containsRegex(/^[xtfv]\\([a-z]{2}\\)$/)").addClass("active");  // x(mb)
$("td:containsRegex(/^[xtfv]\\*\\([a-z]{2}\\)$/)").addClass("active review"); // x*(mb)

$("td:containsRegex(/^[XTFV]$/)").addClass("done");  // X
$("td:containsRegex(/^[XTFV]\\*$/)").addClass("queue review");  // X*
$("td:containsRegex(/^[XTFV]\\*\\([a-z]{2}\\)$/)").addClass("active review");  // X*(mb)

$("td:containsExact(-)").addClass("queue"); // -
"td:containsRegex('/\b[xtfv]\*(?!\()/g')"

\b inside a string literal means backspace ("\b" === "\x08") whereas it means wordbreak in a regex. Try replacing all the \b with \\b.

You should also properly change \( to [(] since in JS, "foo\(bar\)" === "foo(bar)".

发布评论

评论列表(0)

  1. 暂无评论