REGEX необходим в Java для извлечения всех сообщений WARN с описанием может быть или не быть многострочным сообщением - PullRequest
3 голосов
/ 24 апреля 2020

Я пытаюсь написать регулярное выражение для ввода текста, где я должен извлечь весь код WARN с сообщением впереди. В общем случае WARN может быть или не быть многострочным, как показано ниже.

[C] L1250 WARN  k2 bw34 Flex - Sockets:<16>, ThreadsPerCore:<1>
[C] L1250 WARN  For abcd (analytical and transactional workloads). For 12s Systems and above, should be
                disabled.
[C] L1250 INFO  For abcd (analytical workloads), Hyperthreading should be enabled , 8s, 12s, 14d, 34t
                d above.
[C] L1250 WARN  Intel's Hyperthreading on 18+ Socket system disabled. Should be disabled urgently
                fix it!
[C] L1300 OK    CPU governors set as recommended
[C] L1250 WARN  Intel's Hyperthreading on 8+ Socket system disabled.

Первоначально я начал с регулярного выражения: (WARN). * (\ B | \ B), это захватывает до конца слова / граница без слов, которая не захватывает следующую многострочность (продолжение описания WARN).

Тогда я попробовал-> WARN. + ([\ S \ s] *?) + (? = \ [C \]) но это не захватывает последнюю строку WARN, так как больше нет маркера [C].

enter image description here

Ответы [ 2 ]

2 голосов
/ 24 апреля 2020

Вы можете получить свои совпадения, не используя [\s\S]* или однострочный вариант, сопоставив все строки, которые не начинаются с [C]

\bWARN\h+.*(?:\R(?!\[C]).*)*

Объяснение

  • \bWARN Соответствует WARN, которому предшествует граница слова, чтобы не быть частью большего слова
  • \h+.* Соответствует 1+ горизонтальным пробелам
  • (?: Группа без захвата
    • \R(?!\[C]).* Соответствует юникодной последовательности новой строки, утверждая, что строка не начинается с [C]
  • )* Закрыть группу и повторить 0+ раз

Regex demo | Java демо

Например:

String regex = "\\bWARN\\h+.*(?:\\R(?!\\[C]).*)*";
String string = "[C] L1250 WARN  k2 bw34 Flex - Sockets:<16>, ThreadsPerCore:<1>\n"
     + "[C] L1250 WARN  For abcd (analytical and transactional workloads). For 12s Systems and above, should be\n"
     + "                disabled.\n"
     + "[C] L1250 INFO  For abcd (analytical workloads), Hyperthreading should be enabled , 8s, 12s, 14d, 34t\n"
     + "                d above.\n"
     + "[C] L1250 WARN  Intel's Hyperthreading on 18+ Socket system disabled. Should be disabled urgently\n"
     + "                fix it!\n"
     + "[C] L1300 OK    CPU governors set as recommended\n"
     + "[C] L1250 WARN  Intel's Hyperthreading on 8+ Socket system disabled.";

Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
Matcher matcher = pattern.matcher(string);

while (matcher.find()) {
    System.out.println(matcher.group(0));
}

Выход

WARN  k2 bw34 Flex - Sockets:<16>, ThreadsPerCore:<1>
WARN  For abcd (analytical and transactional workloads). For 12s Systems and above, should be
                disabled.
WARN  Intel's Hyperthreading on 18+ Socket system disabled. Should be disabled urgently
                fix it!
WARN  Intel's Hyperthreading on 8+ Socket system disabled.

Если [C] не является границей другим вариантом является проверка, не содержит ли следующая строка одну из WARN, INFO или OK

 \bWARN\h+.*(?:\R(?!.*\h(?:WARN|INFO|OK)\h).*)*

Regex demo

In Java

String regex = "\\bWARN\\h+.*(?:\\R(?!.*\\h(?:WARN|INFO|OK)\\h).*)*";
1 голос
/ 24 апреля 2020

Попробуйте это регулярное выражение с опцией global и в одну строку : WARN.*?(?=\[C\]|$)

Это будет все, начиная с WARN, до следующего '[C]' или конец входной строки.

Демо: https://regex101.com/r/KZXWwL/1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...