Match specific string which not contains specific pattern

Viewed 53

I have urls and want to match only those which match this pattern

^/zxp/companies/.*?/queries/.*?$

but not contains this type=inbox - so for example - regexp should give following results:

"/zxp/companies/432523/queries/4344?read=2&type=inbox"   -> FALSE
"/zxp/companies/432523/queries/4344?type=inbox&read=2"   -> FALSE
"/zxp/companies/432523/queries/4344?type=query&read=2"   -> TRUE
"/zxp/companies/432523/queries/4344"                     -> TRUE
"/zxp/companies/432523/buildings/4344?type=query&read=2" -> FALSE
"/zxp/companies/432523/buildings/4344"                   -> FALSE

I try this but get wrong results (good only when type=inbox is at the end of string)

let re = /^\/zxp\/companies\/.+?\/queries\/.*(?<!type=inbox)$/

let tests = [
  "/zxp/companies/432523/queries/4344?read=2&type=inbox",
  "/zxp/companies/432523/queries/4344?type=inbox&read=2",
  "/zxp/companies/432523/queries/4344?type=query&read=2",
  "/zxp/companies/432523/queries/4344",
  "/zxp/companies/432523/buildings/4344?type=query&read=2",
  "/zxp/companies/432523/buildings/4344",
]



tests.forEach(t => console.log(`${t} -> ${re.test(t)}`))

How to do it using JavaScript RegExp?

3 Answers

The pattern that you tried asserts that the string does not end with type=inbox using (?<!type=inbox)$ which is a negative lookbehind.

You can use a negative lookahead instead, adding it after /queries/, to assert that from that position type=inbox does not occur at the right.

Note that it would also match /zxp/companies/432523/queries/

^\/zxp\/companies\/.+?\/queries\/(?!.*\btype=inbox\b).*$

Regex demo

A bit more specific variant of the pattern could be

^\/zxp\/companies\/\d+\/queries\/\d+\b(?!.*\btype=inbox\b).*$

Regex demo

let re = /^\/zxp\/companies\/.+?\/queries\/(?!.*type=inbox).*$/

let tests = [
  "/zxp/companies/432523/queries/4344?read=2&type=inbox",
  "/zxp/companies/432523/queries/4344?type=inbox&read=2",
  "/zxp/companies/432523/queries/4344?type=query&read=2",
  "/zxp/companies/432523/queries/4344",
  "/zxp/companies/432523/buildings/4344?type=query&read=2",
  "/zxp/companies/432523/buildings/4344",
]



tests.forEach(t => console.log(`${t} -> ${re.test(t)}`))


As there is more support in Javascript to use a lookbehind, another option could be a variant of the pattern that you tried, asserting that the part after the last / does not contain type=inbox.

^\/zxp\/companies\/.+?\/queries\/.*(?<!\btype=inbox\b[^\r\n/]*)$

Regex demo

you can try this:

^\/zxp\/companies\/.*?\/queries\/(?!.*?type=inbox).*?$

I hope that this will be useful for you.

enter image description here

I recomend to you this page to do regex test: https://regexr.com/

enter image description here

For these case select in the "Flags" option and choose "Global" for multiple matches and "MultiLine" for match "^$" in multiple lines

let checkIfType = /type=inbox/;
myString = 'checkmystringtype=inbox';
if(!checkIfType.test(myString)){
  //code here will work if there is no 'type=inbox' inside string
}
Related