Skip to content
Advertisement

Match specific string which not contains specific pattern

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?

Advertisement

Answer

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=inboxb).*$

Regex demo

A bit more specific variant of the pattern could be

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

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=inboxb[^rn/]*)$

Regex demo

Advertisement