views:

4014

answers:

5

I think I must just be really tired, because this should be really simple, but it's just not working for me. I want to match a portion of a string using a regex and then access that parenthesized substring.

var myString = "something format_abc"; // I want "abc"

var arr = /(?:^|\s)format_(.*?)(?:\s|$)/(myString);

console.log(arr);     // prints: [" format_abc", "abc"] .. so far so good.
console.log(arr[1]);  // prints: undefined  (???)
console.log(arr[0]);  // prints: format_undefined (!!!)

can anyone see what I'm doing wrong?


Update: I've discovered that there was nothing wrong with the regex code above: the actual string which I was testing against was this:

"date format_%A"

Reporting that "%A" is undefined seems a very strange behaviour, but not directly related to this question, so I've opened a new one here. Thanks to everyone who responded.


Update: The issue was that console.log takes its parameters like a printf statement, and since the string I was logging ("%A") had a special value, it was trying to find the value of the next parameter.

Since this was just a silly bug on my part, I'll now close this question.

+16  A: 

You can access capturing groups like this:

var myString = "something format_abc";
var myRegexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
var match = myRegexp.exec(myString);
alert(match[1]);  // abc

And if you there are multiple matches you can iterate over them:

while (match != null) {
    match = myregexp.exec(myString);

    // matched text: match[0]
    // match start: match.index
    // capturing group n: match[n]
}
CMS
+1  A: 

Using your code:

console.log(arr[1]);  // prints: abc
console.log(arr[0]);  // prints:  format_abc

Edit: Safari 3, if it matters.

eyelidlessness
+2  A: 
var myString = "something format_abc";
var arr = myString.match(/\bformat_(.*?)\b/);
console.log(arr[0] + " " + arr[1]);

The \b isn't exactly the same thing (works on "--format_foo/", doesn't work on "format_a_b") though... But I wanted to show an alternative to your expression, which is fine. Of course, the match call is the important thing.

PhiLho
A: 

Your code works for me (FF3 on Mac) even if I agree with PhiLo that the regex should probably be:

/\bformat_(.*?)\b/

(But, of course, I'm not sure because I don't know the context of the regex.)

PEZ
it's a space-separated list so I figured \s would be fine. strange that that code wasn't working for me (FF3 Vista)
nickf
Yes, truly strange. Have you tried it on its own in the Firebug console? From an otherwise empty page I mean.
PEZ
A: 

Your syntax probably isn't the best to keep. FF/Gecko defines RegExp as an extension of Function.
(FF2 went as far as typeof(/pattern/) == 'function')

It seems this is specific to FF -- IE, Opera, and Chrome all throw exceptions for it.

Instead, use either method previously mentioned by others: RegExp#exec or String#match.
They offer the same results:

var regex = /(?:^|\s)format_(.*?)(?:\s|$)/;
var input = "something format_abc";

regex(input);        //=> [" format_abc", "abc"]
regex.exec(input);   //=> [" format_abc", "abc"]
input.match(regex);  //=> [" format_abc", "abc"]
Jonathan Lonowski