1

I try to figure out the correct regex to replace the last segment of an url with a modified version of that very last segment. (I know that there are similar threads out there, but none seemed to help...)

Example:

https://www.test.com/one/two/three/mypost/
--->
one/two/three?id=mypost


https://www.test.com/one/mypost/
--->
one?id=mypost

Now I am stuck here: https://regex101.com/r/9GqYaU/1

I can get the last segment in capturing group 2 but how would I replace it? I think I will have to something like this:

  const url = 'https://www.test.com/one/two/three/mypost/'
  const regex = /(http[s]?:\/\/)([^\/]+\/)*(?=\/$|$)/
  const path = url.replace(regex, `${myUrlWithoutTheLastSegmentAnd WithoutHTTPS}?id=$2`)
  return path

But I have no idea how to get the url without the last segment. I have currently only access to the whole string or group 1 (which is useless in this case) and then group 2, but not the string without group 2.

I would be very glad for any help here. Sometimes I just lack the knowledge of what is possible with regex and how to achieve it.

Thank you in advance.

Cheers

2 Answers 2

1

You could use the URL class to extract the pathname and substring to remove the first '/'.

Then, you could put the last part of the pathname in a group and use it as a reference $1 for the replacement.

const url = new URL('https://www.test.com/one/two/three/mypost/').pathname.substring(1)

console.log(url.replace(/\/([^/]*)\/$/, '?id=$1'))

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

Comments

1

I came across your question yesterday and agree with going down the route of parsing the URL. Once you get there you could even use JavaScript array methods which I prefer to string methods like:

pathname.split("/").filter(p => p.length).pop()

This would separate each folder, ignore any with no length (i.e. handle a trailing slash) and return the last one (mypost).

Anyway, I am also learning regex so sometimes when I find a question like this I just try to find the answer anyway as the best way of learning is doing. It took 24 hours 😂 I came up with this:

/(https?:\/\/).+?([a-z-]*)\/?$/gm

(https?:\/\/) you know what this does. Small correction, you don't need the square brackets. Question mark matches 0 or 1 of the preceding character. As we're only matching s this just works. If you wanted to match s or z you would use [sz]?. I think.

.+? this is the cool one I think I will use in future now I found it. The question mark here has a different meaning - it makes .+ (which means one or more of any character) non-greedy. That means it stops applying once it reaches the next rule. Which is...

([a-z-]*) any number of letters or a hyphen. You should maybe change this to include numbers and upper case.

\/? Optional slash

$ all this must apply at the end of the string.

Here is a demo https://regex101.com/r/mQNkIS/1

1 Comment

24h. haha. Nice. Thanks a lot for your elaborate answer! I think this will help me somewhere in my future when I stumble across regex the next time ;).

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.