Dustin
Dustin

Reputation: 455

Regular Expression: Match whole numbers in string

I'm trying to match numbers using JavaScript in a string with the following format:

NUM;#username;#NUM;#username

so for example, in the following string:

252;#Lemmywinks07;#27;#Trogdor

I would capture 252 and 27.

However, I'm having issues building a regular expression that captures both numbers. I thought that using a global would match both, but when I run the following:

/\d+/g.exec("252;#Lemmywinks07;#27;#Trogdor");

It returns: [252] and not [252, 27]

I should note that I do not want to match numbers in a username (which usernames cannot only be numbers). So it looks like I would match whole numbers that are either between ";#" or a whole number that precedes ";#".

Thanks in advance!

EDIT:

Examples now include numbers in usernames. I do not want to match numbers in usernames.

Upvotes: 0

Views: 1131

Answers (3)

Rion Williams
Rion Williams

Reputation: 76557

If Usernames Do Not Have Numbers In Them...

To find matches, you'll actually want to use the match() function as opposed to exec() :

var input = '252;#Lemmywinks;#27;#Trogdor';
var output = input.match(/\d+/g); // yields ['252', '27'];

If Usernames Do Have Numbers In Them...

Alternatively, you could split your existing string into individual components using the ; and # characters via the split() function and test each section accordingly :

var input = '252;#Lemmywinks2;#27;#Trogdor';
var output = input.split(/[;#]/).filter(function(x){ return (/^\d+$/g).test(x); }); 

Upvotes: 3

Denys Séguret
Denys Séguret

Reputation: 382150

Don't use exec but match when you want to get all matches:

"252;#Lemmywinks;#27;#Trogdor".match(/\d+/g);

exec is meant to be used iteratively, you would have to loop until there's no more result, while match immediately gives you an array.

To only take numbers that are full fields, I wouldn't use a regex here, I would have just split:

"252;#Lemmywinks;#27;#Trogdor".split(";#").map(Number).filter(v=>v===v)

(note that this solution also gives you directly numbers instead of strings)

Upvotes: 3

Aaron
Aaron

Reputation: 24802

You could match the whole line and retrieve the appropriate groups with the following regex :

var linePattern = /(\d+);[^;]*;#(\d+);[^;]*/

Then data.match(linePattern)[1] would return the first number, data.match(linePattern)[2] the second number and data.match(linePattern)[0] the whole line.

While this approach is heavier than matching numbers in the line or splitting around the delimiter, it has the advantage of checking if a line respects the expected pattern and avoids returning incoherent results for anomalous entries.

Upvotes: 1

Related Questions