2016-11-28 6 views
2

Я пытаюсь захватить строку в файле журнала, используя библиотеку регулярных выражений onigurama (в Logstash), используя отрицательный внешний вид, но все равно кажется, что она соответствует строке, которой она не должна. Я пытаюсь соответствовать только исключение верхнего уровня, а не один, начиная с вызвано следующими причинами:regex onigurama Отрицательный lookbehind не работает

Кто-то помог мне написать эту

Испытано на Rubular http://rubular.com/r/N3AzySNHiS

Испытано Regex

^(?<!Caused by:).*?Exception 

(?<!^Caused by:).*?Exception 

Сообщение:

2016-11-15 05:19:28,801 ERROR [App-Initialisation-Thread] appengine.java:520 Failed to initialize external authenticator myapp Support Access || [email protected]:/mnt/data/install/assembly [email protected] 
java.lang.IllegalArgumentException: Could not check if provided root is a directory 
    at com.myapp.jsp.KewServeInitContextListener$1.run(QServerInitContextListener.java:104) 
    at java.lang.Thread.run(Thread.java:745) 
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) 

Logstash результат

"exception" => "Caused by: java.nio.file.NoSuchFileException" 
+0

Попробуйте '^ (?! Caused by:). *? Exception' или'^(?! Caused by:) (? . *? Исключение) ' –

+0

Спасибо за ответ 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

+0

Я подозреваю, что существует некоторая настройка, которая делает символ '.' в регулярном выражении совпадающим символом строки. Или какой-либо другой вариант, например Ignore whitespace, включен. Проверьте, включен ли режим MULTILINE в любом месте. Кроме того, хорошая идея - проверить '^ (?! Caused \ by:) (? [^ \ r \ n] *? Исключение)' regex –

ответ

1

Кажется, есть некоторые дополнительные опции, установленные в вашей среде Logstach. Из моих тестов я подозреваю, что опция «verbose» или «ignore whitespace» включена. Кроме того, чтобы исключить какие-либо другие проблемы с . (которые могут быть пересмотрены, чтобы соответствовать символам перевода строк), вы можете использовать однозначный [^\r\n] (любой символ, не \r и \n):

^(?!Caused\ by:)(?<exception>[^\r\n]*?Exception) 
      ^^     ^^^^^^^ 

Экранированного пространство всегда будет соответствовать одно регулярное пространство.

+1

Еще раз спасибо Wiktor! отлично работать и ценить объяснение. – Arturski

+0

Да, спасибо Wiktor, кстати, нам удалось избавиться от двойного результата, удалив? , поэтому последнее регулярное выражение было '^ (?! Caused \ by:) ([^ \ r \ n] *? Исключение)' – Arturski

+0

Это означает ['named_captures_only'] (https://www.elastic.co/ guide/en/logstash/current/plugins-filters-grok.html # plugins-filters-grok-named_captures_only) было установлено на * false *. Если он был по умолчанию (* true *), вызывается только указанная группа захвата. –

0

Примечание. В этом ответе я предполагаю, что две отдельные строки журнала, указанные в задаче и повторяющиеся ниже, не содержат строк новой строки и были обработаны через многострочный плагин кодека в 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 при использовании жадных или неохотно кванторов.