Regex finds catch blocks without log

I am using regex with PowerGrep to search through a bunch of files. I work with java files, and my goal is to find all block locks that do not contain the word log inside the block so that I can add a log. There are many files, so going through them manually is not realistic.

Examples of what should be found

 catch (Exception e) { //comment# int math = 1 +2 * (3); String email = " email@example.com "; anothermethod.call(); //no logging } 

and

 catch(AnotherException e ) {} //no logging 

Examples of what should not be

 catch(AnotherException e ) { //some code log.error("Error message"); //some more code } 

and

 catch(BadE_xception e) { log.error(e); } 

I am not very good at regular expression, but this is what I still have:

start of catch block: catch\s*\(\s*\w*\s+\w*\s*\)\s*\{.*?

but then I'm not sure where to go from there to indicate not to contain log . If you have ideas on how to do this without regular expression, this works fine for me as well. Thanks

+6
source share
1 answer

You can get the final level of nested cases, at least.

For a non-nested case, changing the end of your expression:

 catch\s*\(\s*\w*\s+\w*\s*\)\s*\{(?:[^}](?!\blog\b))*\} ^^^^^^^^^^^^^^^^^^^^^^ 

Let me break it.

  • We look strictly at the characters } ; therefore, [^}] . As soon as we find the first one } , we are done.
  • (?!foo) is called a negative outlook. This means: " foo does not follow this point."
  • \b is the word boundary. Surrounding log in \b ensures that we don't catch โ€œfalse positives,โ€ such as clogging and logically. You want a single word "log".
  • (?:foo) is a way of grouping an expression without capturing. This is not important, because now pretend like (foo) . Its purpose is that the whole group can be quantified with * .
  • Combining all this: we check the character by character, each of which is not } , and each does not follow the whole word log .

This ensures that the word log nowhere inside a non-nested catch block.

Now we pass to the enclosed cases. As @TimPietzcker noted, PowerGREP does not yet support recursive expressions, but you can be satisfied with a finite number of sockets for your purposes. Here's an expression for one level of nesting:

 catch\s*\(\s*\w*\s+\w*\s*\)\s*\{(?:[^{}](?!\blog\b)|\{(?:[^}](?!\blog\b))*\})*\} ^ ^======================== 

We added the symbol { to the character class that we donโ€™t like. This is due to the fact that if we encounter this symbol, we want to switch through alternation ( | ) in the enclosed case, which, as you can see, comparing the part underlined with = signs, is an exact copy of the original "internal" expression. You can continue to nest this way as much as you want to capture an arbitrary number of balanced nests.


Here is a template for 10 levels of nesting, which should be sufficient for most applications of this type.

 catch\s*\(\s*\w*\s+\w*\s*\)\s*\{(?:SEED|\{(?:SEED|\{(?:SEED|\{(?:SEED|\{(?:SEED|\{(?:SEED|\{(?:SEED|\{(?:SEED|\{(?:SEED|\{(?:SEED|\{(?:SEED)*\})*\})*\})*\})*\})*\})*\})*\})*\})*\})*\} 

where SEED is the recursion seed, [^{}](?!\blog\b) . I wrote this so that it is visually easier to remove or add recursions as I wish. Highlighted above:

 catch\s*\(\s*\w*\s+\w*\s*\)\s*\{(?:[^{}](?!\blog\b)|\{(?:[^{}](?!\blog\b)|\{(?:[^{}](?!\blog\b)|\{(?:[^{}](?!\blog\b)|\{(?:[^{}](?!\blog\b)|\{(?:[^{}](?!\blog\b)|\{(?:[^{}](?!\blog\b)|\{(?:[^{}](?!\blog\b)|\{(?:[^{}](?!\blog\b)|\{(?:[^{}](?!\blog\b)|\{(?:[^{}](?!\blog\b))*\})*\})*\})*\})*\})*\})*\})*\})*\})*\})*\} 
+8
source

Source: https://habr.com/ru/post/949154/


All Articles