6
\$\begingroup\$

I have a string like the one below from which I am extracting the tariff name.

const url = "https://any-api/supplier/tariffSelectionG_E5449168?t=randomChars"

So from the above string, I want text tariffSelectionG_E5449168 and I am using the code below at the moment, which is working fine.

const supplyUrl = "https://any-api/supplier/tariffSelectionG_E5449168?t=randomChars"
 if(supplyUrl.includes('?')) {
 const url = supplyUrl.split('?')
 if(url.length > 0) {
 const tariff = url[0].split('supplier/')
 return tariff[1]
 }
 }

Is there any better way to do the above extracting?

konijn
34.2k5 gold badges70 silver badges267 bronze badges
asked Nov 24, 2021 at 9:21
\$\endgroup\$
2
  • 3
    \$\begingroup\$ You could leverage named capturegroups like re = /https.*?supplier\/(?<param>.*)\?/g; re.exec(supplyUrl).groups["param"] to retrieve the same result more compact. \$\endgroup\$ Commented Nov 24, 2021 at 10:42
  • 1
    \$\begingroup\$ If your environment supports it, you could use the URL constructor. \$\endgroup\$ Commented Nov 24, 2021 at 14:13

5 Answers 5

4
\$\begingroup\$

While it may be unlikely to occur, the URL could contain a hostname with a top-level domain supplier. Currently .supplies is registered to Donuts Inc and someday URLs could have a TLD with supplier, which would lead the current code to not correctly find the target text.

const supplyUrl = "https://my.supplier/supplier/tariffSelectionG_E5449168?t=randomChars"
 if(supplyUrl.includes('?')) {
 const url = supplyUrl.split('?')
 if(url.length > 0) {
 const tariff = url[0].split('supplier/')
 console.log('tariff:', tariff[1])
 }
 }

A more robust solution would use the URL API with the pathname property. For example, if it was known that the last part of the pathname was the tariff string then the array method .pop() could be used:

const supplyUrl = "https://my.supplier/supplier/tariffSelectionG_E5449168?t=randomChars"
console.log('tariff: ', new URL(supplyUrl).pathname.split(/\//).pop());

Otherwise if there is a need to find strings anywhere in the path that start with tariff then a pattern match could be used for that - for example:

const supplyUrl = "https://my.supplier/supplier/tariffSelectionG_E5449168?t=randomChars"
function findTariff(url) {
 const pathParts = new URL(url).pathname.split(/\//);
 for (const part of pathParts) {
 if (part.match(/^tariff/)) {
 return part;
 }
 }
 return -1; // or something to signify not found
}
console.log('tariff: ', findTariff(supplyUrl));

Or one could take a functional approach, which can be more concise:

const supplyUrl = "https://my.supplier/supplier/tariffSelectionG_E5449168?t=randomChars"
function findTariff(url) {
 const pathParts = new URL(url).pathname.split(/\//);
 return pathParts.find(part => part.match(/^tariff/));
}
console.log('tariff: ', findTariff(supplyUrl));

answered Nov 24, 2021 at 17:46
\$\endgroup\$
5
\$\begingroup\$

Super short review;

  • The code should handle the presence or the absence ? in a transparent way
  • The code should probably check for /supplier/ instead of ?

That leaves me with

function extractTariffName(url){
 const resource = '/supplier/';
 if(url.contains(resource)){
 return url.split('?').shift().split(resource).pop();
 }
 //return undefined
}
console.log(extractTariffName('https://any-api/supplier/tariffSelectionG_E5449168?t=randomChars'));
console.log(extractTariffName('https://any-api/supplier/tariffSelectionG_E5449168'));
console.log(extractTariffName('https://any-api/supliar/tariffSelectionG_E5449168'));
answered Nov 24, 2021 at 12:42
\$\endgroup\$
3
\$\begingroup\$

I think for any url related task you have two good tools as

  1. The URL API
  2. The URLPattern API

With the URL constructor you may do like;

var url = new URL("https://any-api/supplier/tariffSelectionG_E5449168?t=randomChars"),
 tariffCode = url.pathname.slice(url.pathname.lastIndexOf("/")+1);

URLPattern API, on the other hand is more powerful and convenient for this job despite being a little comprehensive. Keep in mind that it's a recent API and available in Chrome 95+. Server side, it is available in Deno (which i like very much) and possibly in recent Node versions too.

In this particular case we can generate an URL Pattern which takes the path up until a variable that we declare. This variable represents the url portion of our interest. Lets name it tariff. Accordingly

var pat = new URLPattern({pathname: "/supplier/:tariff"});

Thats it.

Once you receive an url first you can test it's validity against the pattern like;

pat.test("https://any-api/supplier/tariffSelectionG_E5449168?t=randomChars"); // <- true

If true then you can extract your tariff code like

var tariffCode = pat.exec("https://any-api/supplier/tariffSelectionG_E5449168?t=randomChars")
 .pathname.groups.tariff; // <- "tariffSelectionG_E5449168"
answered Nov 25, 2021 at 15:39
\$\endgroup\$
1
  • \$\begingroup\$ Reminder: the URLPattern API is still experimental in 2023 and not implemented in Mozilla Firefox and Safari. \$\endgroup\$ Commented Feb 7, 2024 at 14:30
1
\$\begingroup\$

If you can, use the URL constructor. It is a bit clearer semantically:

const supplyUrl = new URL("https://any-api/supplier/tariffSelectionG_E5449168?t=randomChars");
const parts = supplyUrl.pathname.split("/");
// the 0th item is empty since the pathname starts with a slash
const tariff = parts[2];
answered Nov 24, 2021 at 18:15
\$\endgroup\$
0
\$\begingroup\$

Get text before '?' with split('?').at(), then reverse it and get text before '/' and reverse it back ;) supplyUrl.split('?').at().split('').reverse().join('').split('/').at().split('').reverse().join('')

answered Nov 25, 2021 at 21:39
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.