Соответствовать regex справа налево?

Есть ли какой-либо способ соответствовать regex справа налево? То, что я ищу, является regex, который добирается

MODULE WAS INSERTED              EVENT
LOST SIGNAL ON E1/T1 LINK        OFF
CRC ERROR                        EVENT
CLK IS DIFF FROM MASTER CLK SRC  OF

от этого входа

CLI MUX trap received: (022) CL-B  MCL-2ETH             MODULE WAS INSERTED              EVENT   07-05-2010 12:08:40
CLI MUX trap received: (090) IO-2  ML-1E1        EX1    LOST SIGNAL ON E1/T1 LINK        OFF     04-06-2010 09:58:58
CLI MUX trap received: (094) IO-2  ML-1E1        EX1    CRC ERROR                        EVENT   04-06-2010 09:58:59
CLI MUX trap received: (009)                            CLK IS DIFF FROM MASTER CLK SRC  OFF     07-05-2010 12:07:32

Если я, возможно, сделал соответствие справа налево, я, возможно, записал что-то как все направо от (EVENT|OFF) до второго появления больше чем одного пространства [] +

Лучшее, которым я управлял сегодня, должно получить все от (022) до СОБЫТИЯ с regex

CLI MUX trap received: \([0-9]+\)[ ]+(.*[  ]+(EVENT|OFF))

Но это не действительно, что я хотел :)

править: Какой язык для? На самом деле строка конфигурации для фильтра мы имеем, но мое предположение это пользуется стандартной библиотекой GNU C Regex.

edit2: Мне нравятся ответы о вырезании длиной, но Amarghosh был, вероятно, больше, что я искал. Действительно не знайте, почему я не думал о просто вырезании на длине как:

^.{56}(.{39}).*$

Супер спасибо за быстрые ответы...

13
задан Balroq 7 June 2010 в 13:39
поделиться

6 ответов

Если токены гарантированно разделены более чем одним пробелом, а слова в строке до EVENT | OFF гарантированно разделены одним пробелом - только тогда вы можете искать одиночный пробел- разделенные слова, за которыми следуют пробелы, за которыми следует СОБЫТИЕ или ВЫКЛ

var s = "CLI MUX trap received: (022) CL-B  MCL-2ETH             MODULE WAS INSERTED              EVENT   07-05-2010 12:08:40"
        + "\nCLI MUX trap received: (090) IO-2  ML-1E1        EX1    LOST SIGNAL ON E1/T1 LINK        OFF     04-06-2010 09:58:58"
        + "\nCLI MUX trap received: (094) IO-2  ML-1E1        EX1    CRC ERROR                        EVENT   04-06-2010 09:58:59"
        + "\nCLI MUX trap received: (009)                            CLK IS DIFF FROM MASTER CLK SRC  OFF     07-05-2010 12:07:32"

var r = /\([0-9]+\).+?((?:[^ ]+ )* +(?:EVENT|OFF))/g;
var m;
while((m = r.exec(s)) != null)
  console.log(m[1]);

Вывод:

MODULE WAS INSERTED              EVENT
LOST SIGNAL ON E1/T1 LINK        OFF
CRC ERROR                        EVENT
CLK IS DIFF FROM MASTER CLK SRC  OFF

Регулярное выражение: / \ ([0-9] + \). +? ((?: [^] +) * + (?: EVENT | OFF)) / g

\([0-9]+\)       #digits in parentheses followed by  
.+?              #some characters - minimum required (non-greedy)  
(                #start capturing 
(?:[^ ]+ )*      #non-space characters separated by a space  
` +`             #more spaces (separating string and event/off - 
                 #backticks added for emphasis), followed by
(?:EVENT|OFF)    #EVENT or OFF
)                #stop capturing
2
ответ дан 1 December 2019 в 21:23
поделиться

С регулярным выражением вы можете просто заменить это:

^.{56}|.{19}$

пустой строкой.

Но на самом деле вам нужно всего лишь вырезать строку из «позиции 56» в «длина строки - 19» с помощью функции подстроки. Это проще и намного быстрее, чем регулярное выражение.

Вот пример в JavaScript, другие языки работают примерно так же:

var lines = [
  'CLI MUX trap received: (022) CL-B  MCL-2ETH             MODULE WAS INSERTED              EVENT   07-05-2010 12:08:40',
  'CLI MUX trap received: (090) IO-2  ML-1E1        EX1    LOST SIGNAL ON E1/T1 LINK        OFF     04-06-2010 09:58:58',
  'CLI MUX trap received: (094) IO-2  ML-1E1        EX1    CRC ERROR                        EVENT   04-06-2010 09:58:59',
  'CLI MUX trap received: (009)                            CLK IS DIFF FROM MASTER CLK SRC  OFF     07-05-2010 12:07:32'
];
for (var i=0; i<lines.length; i++) {
  alert( lines[i].substring(56, lines[i].length-19) );
}
3
ответ дан 1 December 2019 в 21:23
поделиться

В .NET вы можете использовать параметр RightToLeft :

Regex RE = new Regex(Pattern, RegexOptions.RightToLeft);
Match theMatch = RE.Match(Source);
20
ответ дан 1 December 2019 в 21:23
поделиться

Как насчет

.{56}(.*(EVENT|OFF))
0
ответ дан 1 December 2019 в 21:23
поделиться

Хорошо ли вписывается входной файл в табличный текст фиксированной ширины, как здесь? Потому что если да, то самое простое решение - просто взять правую подстроку каждой строки, начиная с колонки 56 и заканчивая колонкой 94.

В Unix вы можете использовать команду cut:

cut -c56-94 yourfile

См. также


В Java вы можете написать что-то вроде этого:

String[] lines = {
    "CLI MUX trap received: (022) CL-B  MCL-2ETH             MODULE WAS INSERTED              EVENT   07-05-2010 12:08:40",
    "CLI MUX trap received: (090) IO-2  ML-1E1        EX1    LOST SIGNAL ON E1/T1 LINK        OFF     04-06-2010 09:58:58",
    "CLI MUX trap received: (094) IO-2  ML-1E1        EX1    CRC ERROR                        EVENT   04-06-2010 09:58:59",
    "CLI MUX trap received: (009)                            CLK IS DIFF FROM MASTER CLK SRC  OFF     07-05-2010 12:07:32",
};
for (String line : lines) {
    System.out.println(line.substring(56, 94));
}

Это печатает:

MODULE WAS INSERTED              EVENT
LOST SIGNAL ON E1/T1 LINK        OFF  
CRC ERROR                        EVENT
CLK IS DIFF FROM MASTER CLK SRC  OFF  

Решение с помощью regex

Скорее всего, это не нужно, но что-то вроде этого работает (как показано на ideone. com):

line.replaceAll(".*  \\b(.+  .+)   \\S+ \\S+", "$1")

Как вы можете видеть, это не очень читабельно, и вы должны знать свой regex, чтобы действительно понять, что происходит.

По сути, вы подставляете это в каждую строку:

.*  \b(.+  .+)   \S+ \S+

И заменяете это на то, что совпало с группой 1. Это основано на использовании двух последовательных пробелов исключительно для разделения столбцов в этой таблице.

1
ответ дан 1 December 2019 в 21:23
поделиться

Можете ли вы сделать обработку, ориентированную на поля, а не на regex? В awk/sh это выглядело бы так:

< $datafile awk '{ print $(NF-3), $(NF-2) }' | column

что кажется более чистым, чем указание regex.

0
ответ дан 1 December 2019 в 21:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: