marchello
marchello

Reputation: 2136

Javascript regex replace (encoded) url

I want to alter a server response that contains a url for social login. The url looks like this (I wrapped to multiple line for better readability):

https://www.facebook.com/v2.6/dialog/oauth?client_id=clientid&scope=public_profile,email&response_type=code&redirect_uri=
https%3A%2F%2Fsomeotherurl%3A5000%2Fsignin-facebook
&state=reallylongstring

The part I want to change is on the second line, but in a way that the signin-facebook part is kept, like so:

https://newurl.com/signin-facebook (signin-facebook could be something else like signin-linkedin, etc...)

So the complete replaced url would be:

https://www.facebook.com/v2.6/dialog/oauth?client_id=clientid&scope=public_profile,email&response_type=code&redirect_uri=
https://newurl.com/signin-facebook
&state=reallylongstring

This is as far as I have gotten, this replaces the correct segment, but is leaving the signin-facebook part off:

/^https:\/\/(.*&redirect_uri=)([^&]*)(.*)/

Playground link: https://regexr.com/4j5h6

The url segment to be replaced will be already url encoded by the time the regex engine hits it, so I guess somehow I have to match for a string that is between an encoded / and the &state=... part, but I'm stuck with it for now.

Upvotes: 1

Views: 1314

Answers (3)

ajai Jothi
ajai Jothi

Reputation: 2294

you can use URL API to do this.

Browser support: https://caniuse.com/#feat=url

const url = new URL('https://www.facebook.com/v2.6/dialog/oauth?client_id=clientid&scope=public_profile,email&response_type=code&redirect_uri=https%3A%2F%2Fsomeotherurl%3A5000%2Fsignin-facebook&state=reallylongstring');

url.searchParams.set('redirect_uri', 'https://new.url/xyz');

const newUrl = url.toString();

//output
console.log(newUrl);
/* ignore this - just a style hack for stackoverflow */
.as-console-wrapper {
  top: 0;
}
.as-console-row-code {
  overflow-wrap: break-word;
  white-space: pre-line !important;
  color: green;
  max-width: 500px;
}

Upvotes: 0

The fourth bird
The fourth bird

Reputation: 163362

You could use 2 capturing groups including the http part in the first group:

^(https:\/\/.*&redirect_uri=)[^&]*(signin-[^&]+)
  • ^ Start of string
  • ( Capture group 1
    • https:\/\/.*&redirect_uri= Match from http till &redirect_uri=
  • ) Close group
  • [^&]* Match 0+ times not an ampersand
  • ( Capture group 2
    • signin-[^&]+ Match signin- followed by 1+ not an ampersans
  • ) Close group

Regex demo

In the replacement refer to the 2 capturing groups.

$1https://newurl.com/$2

const regex = /^(https:\/\/.*&redirect_uri=)[^&]*(signin-[^&]+)/g;
const str = `https://www.facebook.com/v2.6/dialog/oauth?client_id=clientid&scope=public_profile,email&response_type=code&redirect_uri=
https%3A%2F%2Fsomeotherurl%3A5000%2Fsignin-facebook&state=reallylongstring`;
const subst = `$1https://newurl.com/$2`;
const result = str.replace(regex, subst);

console.log(result);

Upvotes: 1

anubhava
anubhava

Reputation: 785246

I guess somehow I have to match for a string that is between an encoded / and the &state=..

Since encoded / is %2F, you may use this regex:

/^(https:\/\/.*&redirect_uri=).*%2F([^&]+)(&state=.*)/i

And replace it by:

$1https://newurl.com/$2$3

RegEx Demo

Upvotes: 2

Related Questions