0

I am passing a URL to a block of code in which I need to insert a new element into the regex. Pretty sure the regex is valid and the code seems right but no matter what I can't seem to execute the match for regex!

//** Incoming url's
//** url e.g.   api/223344
//**            api/11aa/page/2017

//** Need to match to the following
//** dir/api/12ab/page/1999
//** Hence the need to add dir at the front

var url = req.url;
//** pass in: /^\/api\/([a-zA-Z0-9-_~ %]+)(?:\/page\/([a-zA-Z0-9-_~ %]+))?$/
var re = myregex.toString();
//** Insert dir into regex: /^dir\/api\/([a-zA-Z0-9-_~ %]+)(?:\/page\/([a-zA-Z0-9-_~ %]+))?$/
var regVar = re.substr(0, 2) + 'dir' + re.substr(2);

var matchedData = url.match(regVar);
matchedData === null ? console.log('NO') : console.log('Yay');

I hope I am just missing the obvious but can anyone see why I can't match and always returns NO?

Thanks

3
  • your regex doesn't work based off your commented values/regex because you put that "dir" into the mix to match against your url but it doesn't exist in your url examples. So.. what are you actually trying to accomplish here? Commented Oct 16, 2017 at 23:00
  • In addition to this, passing a stringified regex object to .match() does not work as you expect. For example, "foo".match(".*") will return "foo" but var x= /foo/.toString(); "foo".match(x) returns null because you are passing "/.*/" (noticed the delimiters) to it, which .match() expects to find literal / chars at that point Commented Oct 16, 2017 at 23:09
  • Yep, sorry less of a question more of a brain dump. Commented Oct 17, 2017 at 16:14

2 Answers 2

2

Let's break down your regex

^\/api\/ this matches the beginning of a string, and it looks to match exactly the string "/api"

([a-zA-Z0-9-_~ %]+) this is a capturing group: this one specifically will capture anything inside those brackets, with the + indicating to capture 1 or more, so for example, this section will match abAB25-_ %

(?:\/page\/([a-zA-Z0-9-_~ %]+)) this groups multiple tokens together as well, but does not create a capturing group like above (the ?: makes it non-captuing). You are first matching a string exactly like "/page/" followed by a group exactly like mentioned in the paragraph above (that matches a-z, A-Z, 0-9, etc.

?$ is at the end, and the ? means capture 0 or more of the precending group, and the $ matches the end of the string

This regex will match this string, for example: /api/abAB25-_ %/page/abAB25-_ %

You may be able to take advantage of capturing groups, however, and use something like this instead to get similar results: ^\/api\/([a-zA-Z0-9-_~ %]+)\/page\/\1?$. Here, we are using \1 to reference that first capturing group and match exactly the same tokens it is matching. EDIT: actually, this probably won't work, since the text after /api/ and the text after /page/ will most likely be different, carrying on...

Afterwards, you are are adding "dir" to the beginning of your search, so you can now match someting like this: dir/api/abAB25-_ %/page/abAB25-_ %

You have also now converted the regex to a string, so like Crayon Violent pointed out in their comment, this will break your expected funtionality. You can fix this by using .source on your regex: var matchedData = url.match(regVar.source); https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/source

Now you can properly match a string like this: dir/api/11aa/page/2017 see this example: https://repl.it/Mj8h

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

1 Comment

Like the .source on the pseudo regex string! Doesn't solve the problem as it now matches against the whole string and doesn't return an array of matches elements, but really like the answer :) Given me food for thought though.
0

As mentioned by Crayon Violent in the comments, it seems you're passing a String rather than a regular expression in the .match() function. maybe try the following:

url.match(new RegExp(regVar, "i"));

to convert the string to a regular expression. The "i" is for ignore case; don't know that's what you want. Learn more here:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp

2 Comments

Using RegExp like this won't work as-is either, because it also requires a string expression but without the delimiters, which is the same issue as just passing the regex-as-a-string to .match(). To solve for this part of the issue, instead of using .toString() on his regex object, he should make use of .source and .flags on his original regex object to breakdown, modify, and rebuild.
Cheers all. I have actually found a good solution to the issue by regretting a new RegEx object from a concatenated string.

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.