views:

58

answers:

3

I want to capture thing in nothing globally and case insensitively.

For some reason this doesn't work:

"Nothing thing nothing".match(/no(thing)/gi);

jsFiddle

The captured array is Nothing,nothing instead of thing,thing.

I thought parentheses delimit the matching pattern? What am I doing wrong?

(yes, I know this will also match in nothingness)

A: 

Parentheses do nothing in this regex.

The regex /no(thing)/gi is same as /nothing/gi.

Parentheses are used for grouping. If you don't put any reference to groups (using $1, $2) or count for group, the () are useless.

So, this regex will find only this sequence n-o-t-h-i-n-g. The word thing does'nt starts with 'no', so it doen't match.


EDIT:

Change to /(no)?thing/gi and will work. Will work because ()? indicates a optional part.

Topera
Ok, so how **do** you find `thing` in `nothing` ;) (downvote not mine, btw)
Peter Ajtai
I've edited the answer...please, check now.
Topera
Nope - http://jsfiddle.net/uGAXb/
Peter Ajtai
Sorry. I read in the question "thing AND nothing", not "thing IN nothing". So you want thing INSIDE nothing. Now I understand.
Topera
+5  A: 

If you use the global flag, the match method will return all overall matches. This is the equivalent of the first element of every match array you would get without global.

To get all groups from each match, loop:

var match;
while(match = /no(thing)/gi.exec("Nothing thing nothing")) 
{ 
  // Do something with match
}

This will give you ["Nothing", "thing"] and ["nothing", "thing"].

Matthew Flaschen
Thanks. That does work, but for some reason, I just thought there was a simpler way of doing it.
Peter Ajtai
Just reading Javascript: The Good Parts, and this is Crockford's suggestion.
Peter Ajtai
+1  A: 

Parentheses or no, the whole of the matched substring is always captured--think of it as the default capturing group. What the explicit capturing groups do is enable you to work with smaller chunks of text within the overall match.

The tutorial you linked to does indeed list the grouping constructs under the heading "pattern delimiters", but it's wrong, and the actual description isn't much better:

(pattern), (?:pattern) Matches entire contained pattern.

Well of course they're going to match it (or try to)! But what the parentheses do is treat the entire contained subpattern as a unit, so you can (for example) add a quantifier to it:

(?:foo){3}  // "foofoofoo"

(?:...) is a pure grouping construct, while (...) also captures whatever the contained subpattern matches.

With just a quick look-through I spotted several more examples of inaccurate, ambiguous, or incomplete descriptions. I suggest you unbookmark that tutorial immediately and bookmark this one instead: regular-expressions.info.

Alan Moore