views:

164

answers:

7

Can someone please explain this JavaScript regular expression for me?

new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ')
+3  A: 

Looks like it's looking for classnames.

Match the start of a newline or whitespace (^|\s), then the classname, then the classname can be followed by a space or the end of line ($|\s).

altCognito
+1  A: 

It searches for the contents of classname in a whitespace-delimited list. It seems that it was made to parse the className property of DOM elements.

MiffTheFox
+1  A: 

Matches that class name if it's preceded by the beginning (^) or a space (\\s) in front of it, and it's followed by a space after it or the end ($).

Eric
A: 

The first fragment matches either whitespace or the beginning of a string. The last fragment similarly matches either whitespace or the end of a string. This is done so that a check for a classname of "foo" doesn't match an element whose only classname is "foobar".

Ben Blank
+11  A: 
(             Either
  ^               the start of the string
|               or
  \\s+            one or more whitespace characters
)             followed by
className       the class name in question
(             followed by either
  \\s+          one or more whitespace characters
|             or
  $             the end of the string
)

So it will match "pog" in:

"pog"
"  pog"
"pog  "
"pog bim"
"bim pog"
"  pog bim"
"bim pog  "
"bim pog pam"

etc.

The second argument to new RegExp() can give options, eg. "i" meaning "case insensitive". In your case you're not passing any options (which is correct if you're dealing with HTML class names - class names should be treated case-sensitively).

RichieHindle
I believe this also traps whats inside the parenthesis for look backs, which wouldn't give you much regardless.
Tom Hubbard
@Tom - correct. You could modify the subpatterns with ?: to prevent match capturing, but it's not really needed in this case.
Peter Bailey
+1, wow, you guys took it to a whole new level
altCognito
A: 

w3schools has some great intro and try yourself tutorials for all sorts of development topics. Check out http://www.w3schools.com/js/js_obj_regexp.asp

And then for pattern matching look for a cheat sheet you like, I always ended up on http://regexlib.com/CheatSheet.aspx

hope these sites help.

BigBlondeViking
+5  A: 

RichieHindle has a great answer. I just wanted to add some info about the purpose of this pattern.

When you're checking if an element has a given CSS class, you want to avoid false positives. If your regexp was too simple, like this

var pattern = new RegExp( className );

Then an element with the class "fooBar" would test positive for a check on the class "foo". These boundary subpatterns exists here to prevent this type of scenario. Here's a demo of it in action

<div id="test1" class="red big">My class is "red big"</div>
<div id="test2" class="red-and-big green">My class is "red-and-big green"</div>
<textarea id="output" rows="10" cols="60"></textarea>

<script type="text/javascript">

    var ta = document.getElementById( 'output' );
    var test1 = document.getElementById( 'test1' );
    var test2 = document.getElementById( 'test2' );

    function hasCssClass( classList, className )
    {
        var pattern = new RegExp( "(^|\\s+)" + className + "(\\s+|$)" );
        return pattern.test( classList );
    }

    function testElement( elem, className )
    {
        var has = hasCssClass( elem.className, className )
        ta.value += elem.id + ' ' + ( has ? 'has' : 'does not have' ) + ' ' + className + "\n";
    }

    testElement( test1, 'red' );
    testElement( test1, 'green' );
    testElement( test1, 'big' );
    testElement( test1, 'red-and-big' );

    testElement( test2, 'red' );
    testElement( test2, 'big' );
    testElement( test2, 'green' );
    testElement( test2, 'red-and-big' );


</script>
Peter Bailey
+1: Nice demo!
RichieHindle
+1, wow, you guys took it to a whole new level
altCognito