0

Strange one here (or maybe not), I am attempting to retrieve two capturing groups via Javascript regex, first group: one or more digits (0-9), second group: one or more word characters or hyphens (A-Z, 0-9, -) but for some reason I never can retrieve the latter group.

Please note: I have purposely included the alternation (|) character as I wish to potentially receive one or the other)

This is the code I am using:

var subject = '#/34/test-data'
var myregexp = /#\/(\d+)|\/([\w-]+)/;
var match = myregexp.exec(subject);
if (match != null && match.length > 1) {
  console.log(match[1]); // returns '34' successfully
  console.log(match[2]); // undefined? should return 'test-data'
}

Funny thing is Regex Buddy tells me I do have two capturing groups and actually highlights them correctly on the test phrase.

Is this a problem in my JavaScript syntax?

2 Answers 2

1

If you change:

var myregexp = /#\/(\d+)|\/([\w-]+)/;

by removing the | alternation meta-character to just:

var myregexp = /#\/(\d+)\/([\w-]+)/;

it will then match both groups. At present, your regex is looking for either \d+ or [\w-]+ so once it matches the first group it stops and the second will be empty. If you remove |, it's looking for \d+ followed by /, followed by [\w-]+ so it will always match either both or none.

Edit: To match on all of #/34/test-data, #/test-data or #/34, you can use #(?:\/(\d+))?\/([\w-]+) instead.

Sign up to request clarification or add additional context in comments.

4 Comments

Sorry I should have mentioned, I would like to match on #/test-data OR #/34 that's why the alternation character was there, how would I do this?
Oh I think I just had a thought, I can use your version, but change + to * to match 0 or many times!
Amazing, thanks. Works well. Probably better than my idea too :)
Just to let you know I advanced on this a bit, just to keep the capturing groups at the correct index positions. This is what I settled on: #(?:/(\d+))?(?:/([\w-]+))? it will keep a match of #/34 in group 1 and #/test-data in group 2 and then both in group 1 & 2 respectively.
1

If you remove the "|" you get the result you want... does this help?

var subject = '#/34/test-data'
var myregexp = /#\/(\d+)\/([\w-]+)/;
var match = myregexp.exec(subject);
if (match != null && match.length > 1) {
  console.log(match[1]); // returns '34' successfully
  console.log(match[2]); // undefined? should return 'test-data'
}

Happy coding!

Edit

I think your problem was, that since you were using the "|", you were telling JS to catch either the first group or the second one, and since JS eval is lazy, when it found the first group, it stopped there... By removing the OR operand from the RegExp, you get both results...(something like an AND).

2 Comments

Please see the response I wrote to mike, I actually need the or test.
Hi Deleteman, I had to accept Mike's answer because his met my requirement I forgot to mention, my fault, but thanks for the effort though!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.