Home > Software design >  Regex For Matching URLs that Share Portions of the Same Format
Regex For Matching URLs that Share Portions of the Same Format

Time:01-20

I am trying to write a Regex for a Cypress test to intercept a call to the backend. I have two calls, both PUTs, that are made to endpoints that look like this:

Call 1: /api/{randomId} Call 2: /api/{randomId}/approval

I need a regex that matches the first but not the second, and a regex that matches the second but not the first.

The second regex is easy: . \/api\/. \/approval will match the second URL but not the first:

regex test result

The first regex though is tough because everything I've tried so far matches both URLs. For example, . \/api\/. matches both URLs:

regex test result

I'm not really familiar with regexes and have tried several options on regexr (like a negative lookahead so that if the random ID is followed by a / it shouldn't match) but nothing has worked so far.

Any suggestions would be greatly appreciated.

CodePudding user response:

With negative lookahead, you can do something like this:

\/api\/(?!. ?\/approval). 

Basically, put the thing you don't want (so, a bunch of chars followed by \approval) entirely in the lookahead.

CodePudding user response:

To test for the first URL you can test for just the random pattern, followed by end of string:

const input = [
  '/api/qwerty123',
  '/api/qwerty123/approval',
  'https://example.com/api/random99',
  'https://example.com/api/random99/approval',
];
const regex1 = /^.*\/api\/[^\/] $/;
const regex2 = /^.*\/api\/[^\/] \/approval$/;

input.forEach(str => {
  let m1 = regex1.test(str);
  let m2 = regex2.test(str);
  console.log(`${str}: regex1 ${m1}, regex2 ${m2}`);
});

Output:

/api/qwerty123: regex1 true, regex2 false
/api/qwerty123/approval: regex1 false, regex2 true
https://example.com/api/random99: regex1 true, regex2 false
https://example.com/api/random99/approval: regex1 false, regex2 true

Explanation of regex1:

  • ^ -- anchor at start of string
  • .* -- greedy scan
  • \/api\/ -- literal /api/
  • [^\/] -- 1 chars that are not /
  • $ -- anchor at end of string

Explanation of regex2:

  • ^.*\/api\/[^\/] -- same as regex, expect for trailing anchor
  • \/approval -- literal /approval
  • $ -- anchor at end of string
  • Related