What I'm trying to do is to extract matching patterns, but one of the patterns could be optional. Let's go example directly.
The target text I'm trying to match would be,
<foo>\n<bar>\n#####<foo>\n#####<bar>
And my regular expression is,
/(#{5})?/
(The reason why I use ? here is because the particular pattern could be optional. For example I don't want the match to be totally a miss rather than just an 'undefined' for this very pattern.)
What I expected as returned by str.match() is,
[ '#####',
'#####',
index: 12,
input: '<foo>\n<bar>\n#####<foo>\n#####<bar>' ]
But actually it's,
[ '',
undefined,
index: 0,
input: '<foo>\n<bar>\n#####<foo>\n#####<bar>' ]
If I use following pattern instead, it'll work fine.
/(#{5})+/
Why?
I tried this in both nodejs/chrome and IE but neither one work which means this behavior is consistent across JS engine. But it doesn't behave the same way one of many tools i tried, regexpal. I'm not sure if that's the tool's own issue or just different implementation.
var re = /(#{5})/;
console.log ("<foo>\n<bar>\n#####<foo>\n#####<bar>".match (re));
console.log ("<foo>\n<bar>\nfoo>\n<bar>".match (re));
output:
[ '#####',
'#####',
index: 12,
input: '<foo>\n<bar>\n#####<foo>\n#####<bar>' ]
null
If it's optional the regexp fails when there's no match and if it fails it returns null.
> /a/.exec("a")
[ 'a', index: 0, input: 'a' ]
> /a/.exec("b")
null
> "a".match(/a/)
[ 'a', index: 0, input: 'a' ]
> "b".match(/a/)
null
Also, don't use String#match(), it's slower than RegExp#exec() and both return the same: