Home > Software design >  regex negative look-behind
regex negative look-behind

Time:11-20

UPD: I need to check if @if(Medellin) so take "City Medellin" but if @if(null) don't take anything

Here is my pattern:

(?<!@if\(null\)).*?@end$

Testing strings:

@if(Medellin) City  Medellin @end

@if(null) City  Medellin @end

I understood that first checks right side, and it takes all string :(

CodePudding user response:

You can use

@if\((?!null\))\w \)\s*(.*?)\s*@end\b

See the regex demo. To match across lines, you will need either (?s)@if\((?!null\))\w \)\s*(.*?)\s*@end\b or @if\((?!null\))\w \)\s*([\w\W]*?)\s*@end\b.

Details:

  • @if\( - a @if( string
  • (?!null\)) - a negative lookahead that fails the match if there is null) string immediately to the right of the current location
  • \w - one or more word chars
  • \) - a ) char
  • \s* - zero or more whitespaces
  • (.*?) - zero or more chars as few as possible
  • \s* - zero or more whitespaces
  • @end\b - @end whole word.

CodePudding user response:

This assertion it true at the first position (?<!@if\(null\)) as there is nothing directly to the left, so .*?@end$ will match the whole string, matching both strings.

If you want to use the lookbehind, you have to match the part between parenthesis first, and then you can use the negative lookbehind to do the assertion:

@if\([^()]*\)(?<!\(null\))\s*(.*?)\s*@end$
  • @if\([^()]*\) Match if followed by a part in parenthesis
  • (?<!\(null\)) After matching that part, assert that what is directly to the left is not if(null)
  • \s*(.*?)\s*@end Match optional whitspace chars, and capture in group 1 as least as possible chars and match @end
  • $ End of string

Regex demo

  • Related