Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why javascript string match includes undefined

I have a regex that is more or less used like this:

'(801) 555-1234'.match(/^(1[-. ]?)?\(?[0-9]{3}\)?[-. ]?[0-9]{3}[-. ]?[0-9]{4}$/)

For some reason this returns

["(801) 555-1234", undefined]

If I add the global flag to the regex (e.g. ...{4}$/g), the undefined value drops out and I get

["(801) 555-1234"]

I'd prefer not to use the g flag if it's not necessary (which it would seem to me it's not, since the regex begins with ^ and ends with $).

P.S. ignore the quality of the regex for it's purpose of matching phone numbers. It may not be ideal, but is from code I'm maintaining. Mostly I'm interested in the ^...$ and the presence/absence of the flag and the undefined value.

Why is undefined showing up, and why does the flag make the difference?

like image 266
jinglesthula Avatar asked Jan 09 '14 16:01

jinglesthula


People also ask

What does match return if no match JavaScript?

JavaScript String match() The match() method returns an array with the matches. The match() method returns null if no match is found.

What does .match do in JavaScript?

match() is an inbuilt function in JavaScript used to search a string for a match against any regular expression. If the match is found, then this will return the match as an array.

What does regex match return?

The Match(String, String) method returns the first substring that matches a regular expression pattern in an input string. For information about the language elements used to build a regular expression pattern, see Regular Expression Language - Quick Reference.


2 Answers

Here is a group:

/^(1[-. ]?)?

.match (without the /g flag) and .exec return groups as part of the array. If the group didn’t match, its value is set to undefined.

Get the first element:

'(801) 555-1234'.match(/^(1[-. ]?)?\(?[0-9]{3}\)?[-. ]?[0-9]{3}[-. ]?[0-9]{4}$/)[0]

If you really, really, really want the single-element array for some reason, you can make it non-capturing:

/^(?:1[-. ]?)?

However, at that point, you have this regular expression anchored to both the start and end of the string and aren’t extracting any information. In that case, it seems like you’re really looking for RegExp.prototype.test:

var PHONE_NUMBER = /^(1[-. ]?)?\(?[0-9]{3}\)?[-. ]?[0-9]{3}[-. ]?[0-9]{4}$/;
var isValid = PHONE_NUMBER.test('(801) 555-1234');
like image 170
Ry- Avatar answered Oct 13 '22 06:10

Ry-


It's because your regex starts with that parenthesized group. The undefined in the result means that nothing matched that part.

When you add the "g" suffix, the behavior of the regex code changes a little, so the return value is different. The "g" ("global") suffix causes the routine to return all the matches of the whole regex; the groups are effectively ignored in that case. For example:

"hello world! nice day today!".match(/\w+/g)

would return an array like this:

["hello", "world", "nice", "day", "today"]
like image 22
Pointy Avatar answered Oct 13 '22 04:10

Pointy