Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to negate string pattern using re2 regex?

I'm using google re2 regex for the purpose of querying Prometheus on Grafana dashboard. Trying to get value from key by below 3 types of possible input strings

 1. object{one="ab-vwxc",two="value1",key="abcd-eest-ed-xyz-bnn",four="obsoleteValues"}
 2. object{one="ab-vwxc",two="value1",key="abcd-eest-xyz-bnn",four="obsoleteValues"}
 3. object{one="ab-vwxc",two="value1",key="abcd-eest-xyz-bnn-ed",four="obsoleteValues"}

..with validation as listed below

  • should contain abcd-
  • shouldn't contain -ed

Somehow this regex

\bkey="(abcd(?:-\w+)*[^-][^e][^d]\w)"

..satisfies the first condition abcd- but couldn't satisfy the second condition (negating -ed).

The expected output would be abcd-eest-xyz-bnn from the 2nd input option. Any help would be really appreciated. Thanks a lot.

like image 585
CdVr Avatar asked Sep 17 '25 03:09

CdVr


2 Answers

If I understand your requirements correctly, the following pattern should work:

\bkey="(abcd(?:-e|-(?:[^e\W]|e[^d\W])\w*)*)"

Demo.

Breakdown for the important part:

(?:                 # Start a non-capturing group.
    -e              # Match '-e' literally.
    |               # Or the following...
    -               # Match '-' literally.
    (?:             # Start a second non-capturing group.
        [^e\W]      # Match any word character except 'e'.
        |           # Or...
        e[^d\W]     # Match 'e' followed by any word character except 'd'.
    )               # Close non-capturing group.
    \w*             # Match zero or more additional word characters.
)                   # Close non-capturing group.

Or in simple terms:

Match a hyphen followed by:

  • only the letter 'e'. Or..
  • a word* not starting with 'e'. Or..
  • a word starting with 'e' not followed by 'd'.

*A "word" here means a string of word characters as defined in regex.

like image 90
41686d6564 stands w. Palestine Avatar answered Sep 18 '25 17:09

41686d6564 stands w. Palestine


Maybe have a go with:

\bkey="((?:ktm-(?:(?:e-|[^e]\w*-|e[^d]\w*-)*)abcd(?:(?:-e|-[^e]\w*|-e[^d]\w*)*)|abcd(?:(?:-e|-[^e]\w*|-e[^d]\w*)*)))"

This would ensure that:

  • String starts with either ktm- or abcd.
  • If starts with ktm-, there should at least be an element called abcd.
  • If starts with abcd, there doesn't have to be another element.
  • Both options check that there must not be an element starting with -ed.

See the online demo

The struggle without lookarounds...

like image 34
JvdV Avatar answered Sep 18 '25 16:09

JvdV