Regex найти блоки catch без журнала

Я использую regex с PowerGrep для поиска по куче файлов. Я работаю с java-файлами, и моя цель-найти все catch блоки, которые не содержат слово log внутри блока, чтобы я мог добавить ведение журнала. Есть много файлов, поэтому пройти через них вручную на самом деле не представляется возможным.

примеры должны можно найти

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

и

catch(AnotherException e ) {}    //no logging

примеры должны Не можно найти

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

и

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

Я не очень опытен с regex, но это то, что у меня есть до сих пор:

начало блока catch: catch\s*\(\s*\w*\s+\w*\s*\)\s*\{.*?

но тогда я не уверен, куда идти оттуда указания не содержат log. Если у вас есть идеи о том, как это сделать без regex, это отлично подходит и для меня. Спасибо

1 ответов


вы можете получить конечный уровень вложенных случаев, по крайней мере.

для случая без вложенности измените конец вашего выражения:

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

давайте разберем это.

  1. мы строго смотрим на не -} символы; отсюда [^}]. Как только мы найдем первый }, мы закончили.
  2. на (?!foo) называется отрицательное утверждение lookahead. Это означает: "этот пункт не затем foo."
  3. на \b является границей слова. Окружающие log на \bs гарантирует, что мы не поймаем "ложные срабатывания", такие как "засорение" и "логическое". Вам нужно единственное слово - "лог".
  4. на (?:foo) - это способ сгруппировать выражение без захвата. Это не важно-пока притворись, что это то же самое, что (foo). Его цель состоит в том, чтобы вся группа могла быть количественно определена *.
  5. положить все это вместе: мы проверяем характер характер, каждый из них не будучи }, и все не за которым следует все слово,log.

это гарантирует, что слово log нигде в не вложенном блоке catch.

теперь перейдем к вложенным случаям. Как отметил @TimPietzcker, PowerGREP еще не поддерживает рекурсивные выражения, но для ваших целей вы можете быть удовлетворены конечная количество вложенностей. Вот выражение для один уровень вложенности:

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

мы добавили { характер к классу символов, которые нам не нравятся. Это потому, что если мы сталкиваемся с этим персонажем, мы хотим переключиться через чередование (|) к вложенному случаю, который, как вы можете видеть, сравнивая часть, подчеркнутую = знаки, является точной копией оригинального" внутреннего " выражения. Вы можете продолжать гнездиться таким образом, сколько хотите, чтобы захватить произвольное число сбалансированных гнезд.


вот шаблон для 10 уровней вложенности, которого должно быть достаточно для большинства приложений такого рода.

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

здесь SEED это семя рекурсии,[^{}](?!\blog\b). Я написал это так, чтобы визуально было проще удалить или добавить рекурсии по желанию. Расширяется, выше становится:

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))*\})*\})*\})*\})*\})*\})*\})*\})*\})*\})*\}