Примечание. В этом ответе я предполагаю, что две отдельные строки журнала, указанные в задаче и повторяющиеся ниже, не содержат строк новой строки и были обработаны через многострочный плагин кодека в logstash или удалены каким-либо образом.
TL; DR Решение Используя отрицательный
просмотра назад
Отрицательный взгляд за будет работать, если он дан соответствующий якорь впоследствии. Глядя на этих двух линий это будет хорошо работать:
^(?<!Caused by:)java.*Exception
Примечание: это может быть просто ^(?<!Caused by:)j.*Exception
, но я думаю, что java
делает его более удобным для чтения.
Объяснение проблемы с примерами кода
Проблема с заданными регулярными выражениями: ^(?<!Caused by:).*?Exception
и (?<!^Caused by:).*?Exception
это неохотно *?
квантор, что позволяет что-то будет соответствовать 0 или более раз. Теперь, как объяснено в этом документе answer, двигатель регулярного выражения запускается в начале строки и перемещается влево для записи. Наименьшее возможное количество символов (так как оно неохотно) - это не что иное, как двигатель не может соответствовать Exception
, а затем он постепенно пытается сопоставить что-либо (.
) перед Exception
(«backtracking»), перемещающееся влево, чтобы писать.
Таким образом, двигатель регулярных выражений продолжает пытаться сопоставить еще один символ за раз (слева направо), пока Exception
не будет найден после того, что потребляется.Поэтому строка
Caused by: java.nio.file.NoSuchFileException: fh-ldap-config/ at com.upplication.s3fs.util.S3Utils.getS3ObjectSummary(S3Utils.java:55) at com.upplication.s3fs.util.S3Utils.getS3FileAttributes(S3Utils.java:64)
, потому что двигатель израсходовал весь до Exception
и Caused by:
не появляется перед этим матчем ли матч. По сути, .*?
поглотил Caused by:
, который ищет отрицательный lookbehind.
Понимание Deeper
Чтобы понять, что движок регулярных выражений на самом деле делает с lookarounds я рекомендую просмотр этого answer
Я думаю, что это легко увязнуть квантификаторами и lookarounds и в качестве общего правила I подумайте, что это должно быть закреплено чем-то конкретным (не .
). Чтобы понять, что я имею в виду, давайте посмотрим на небольшую вариацию на заданное регулярное выражение с жадным *
квантификатором. Регулярное выражение ^(?<!Caused by:).*Exception
также соответствует цитируемой строке.
Причина, по которой жадный *
отборщик начинает с потребления всей строки, а затем возвращается назад налево, как объясняется в первом связанном ответе выше. По той же причине (но с другой стороны), когда двигатель соответствует Exception
, он удерживает все, начиная с начала строки до Exception
. Затем он смотрит за то, что он потребляет, и не находит Caused by:
и успешно соответствует строке.
В сводке, как общее правило
Всегда анкерное lookarounds при использовании жадных или неохотно кванторов.
Попробуйте '^ (?! Caused by:). *? Exception' или'^(?! Caused by:) (?. *? Исключение) ' –
Спасибо за ответ Wiktor, сначала вернул' exception "=>" в java.lang.Thread.run (Thread.java:745) \ nCaused by: java.nio.file.NoSuchFileException ", второй возвращает 2 результата' "exception" => [ [0 ] "в java.lang.Thread.run (Thread.java:745) \ nПокрывается: java.nio.file.NoSuchFileException", [1] "в java.lang.Thread.run (Thread.java:745) \ nCaused by: java.nio.file.NoSuchFileException "' – Arturski
Я подозреваю, что существует некоторая настройка, которая делает символ '.' в регулярном выражении совпадающим символом строки. Или какой-либо другой вариант, например Ignore whitespace, включен. Проверьте, включен ли режим MULTILINE в любом месте. Кроме того, хорошая идея - проверить '^ (?! Caused \ by:) (? [^ \ r \ n] *? Исключение)' regex –