1

I need to find certain chunks of code that are missing the raise keyword as follows:

These are the types of matches that I'm searching for

except
  FreeAndNil(result);
end;

While these should be ignored:

except
  FreeAndNil(result);
  raise;
end;

Bear in mind that between the except and end; keywords there may be any type or length of text.

I tried the following regex expression: except((?!raise).)*end; however it does not work on a multiline scenario.

EpaXapate
  • 171
  • 10
  • 2
    If there is an option to make the dot match a newline you could use your pattern https://regex101.com/r/puLnO6/1 or perhaps with an inline modifier `(?s)except((?!raise).)*end;` or `except((?!raise)[\s\S])*end;` – The fourth bird Dec 05 '19 at 15:15
  • 2
    You could also match the newlines instead `except\s*\n(?:(?![\t ]*\b(?:except|raise;)$).*\n)*end;` https://regex101.com/r/Wx2bGx/1 – The fourth bird Dec 05 '19 at 15:19
  • I like the idea of the 4th bird. Is delphi using PCRE? If so, you can even use somewhat with [`(*SKIP)(*F)`](https://stackoverflow.com/questions/24534782/how-do-skip-or-f-work-on-regex) like this one: [`except\s*(?:\n.*)*?(?:\n\s*(?:end|raise(*SKIP)(*F));)`](https://regex101.com/r/DLNGKZ/1) – bobble bubble Dec 05 '19 at 15:44
  • 1
    @bobblebubble I found [this page](https://stackoverflow.com/questions/14208789/delphi-regex-library-and-unicode-characters) so I think it does, not really sure though as I have no experience with delphi. That is a nice pattern you suggested, even less steps. – The fourth bird Dec 05 '19 at 15:56
  • 1
    @bobblebubble I think you might even shorten it to [except\s*(?:\R.*)*?\R\s*(?:end|raise(*SKIP)(*F));](https://regex101.com/r/WJwnsh/1) You should post it as well if it supports PCRE :) – The fourth bird Dec 05 '19 at 16:21
  • As suggested by @Thefourthbird I ended up using `except((?!raise)[\s\S])*end;` as it matched the requirements I needed. Thank you very much for your sugestions. – EpaXapate Dec 05 '19 at 16:31
  • 1
    @Thefourthbird Indeed! dunno why I put that around! thanks:) – bobble bubble Dec 05 '19 at 16:52

1 Answers1

3

An option matching the newlines could be matching all the lines between except and end by using a negative lookahead asserting that those lines do not start with either of except or end:

\bexcept\s*\r?\n(?:(?!(?:except|[\t ]+raise;)$).*\r?\n)*end;

In parts

  • \bexcept\s*\r?\n Match except, 0+ whitespace chars and a newline
  • (?: Non capturing group
    • (?! Negative lookahead, assert what is on the right is not
      • (?:except|[\t ]+raise;)$) Match either except or 1+ spaces or tabs and raise; followed by the end of the string.
    • ) Close lookahead
    • .*\r?\n Match the whole line followed by a newline
  • )* Repeat the non capturing group 0+ times
  • end; Match literally

Regex demo

The fourth bird
  • 154,723
  • 16
  • 55
  • 70