Нужна помощь с регулярным выражением - PullRequest
1 голос
/ 28 марта 2011

В моем файле журнала записи регистрируются с маркером начала и конца. Как ниже

WY_LOG_TYPE_ERROR << **<br> Это первая ошибка
бла - бла - бла
** >>

WY_LOG_TYPE_ERROR << **<br> Это вторая ошибка
бла - бла - бла
** >>

WY_LOG_TYPE_ERROR << **<br> Это третья ошибка
бла - бла - бла
** >>

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

В настоящее время я использую следующий reg-exp:
WY_LOG_TYPE_ERROR \ s * << \ * \ * ((|. \ П) *) \ * \ * >> $

Теперь $ 1 содержит все, что находится между маркером начала первой записи и маркером конца последней записи.
То, что я хочу, это содержимое между маркером начала и конца последней записи. Меня не интересуют другие записи.

Может ли кто-нибудь изменить этот reg-exp в соответствии с моими потребностями.

Редактировать: я использую Perl Reg-Ex

Редактировать: мне нужно использовать reg-exp, поскольку я использую SEC для обработки журнала ошибок.

Ответы [ 5 ]

2 голосов
/ 28 марта 2011

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

Это можно решить гораздо проще, просто используя последнюю подстроку поиска WY_LOG_TYPE_ERROR

Например, в javascript (хотя это было бы просто реализовать практически на любом языке, который я могу себе представить)

var log = "WY_LOG_TYPE_ERROR <<** ... **>>",
    last = log.substr(log.lastIndexOf("WY_LOG_TYPE_ERROR"));

Насколько это было просто?Не говоря уже о более быстром, поскольку lastIndexOf начинается с конца строки (который будет масштабироваться для произвольно больших строк журнала / файлов / потоков), и нам не нужно было создавать конечный автомат (то есть создавать регулярное выражение).

1 голос
/ 28 марта 2011

Вы также можете использовать отрицательный взгляд , чтобы утверждать, что это последняя запись журнала:

m/WY_LOG_TYPE_ERROR <<\*\*(?!.*WY_LOG_TYPE_ERROR <<\*\*)(.*)\*\*>>/s

Сначала вы найдете заголовок записи, а затем утверждаете, что в заголовке записи больше нетэтот файл, и, наконец, вы захватите реальное сообщение в $ 1.

Результат будет:

This is the third error
blah - blah - blah

Весь Perl будет:

if ($logfile =~ m/WY_LOG_TYPE_ERROR <<\*\*(?!.*WY_LOG_TYPE_ERROR <<\*\*)(.*)\*\*>>/s) {
    $last_record = $1;
} else {
    $last_record = "";
}
1 голос
/ 28 марта 2011

Вам нужно сделать «не жадный» матч. * по умолчанию является жадным, что означает, что он будет максимально соответствовать. Большинство языков используют *? для обозначения нежадного или кратчайшего совпадения.

0 голосов
/ 28 марта 2011

Вот способ сделать это:

#!/usr/bin/perl
use strict;
use warnings;

my $err;
while(<DATA>) {
    $err ='' if (/^WY_LOG_TYPE_ERROR <</);
    $err .= $_ if (/^WY_LOG_TYPE_ERROR <</ .. /^\*\*>>/);
}
print $err;

__DATA__
WY_LOG_TYPE_ERROR <<**
This is the first error
blah - blah - blah
**>>

WY_LOG_TYPE_ERROR <<**
This is the second error
blah - blah - blah
**>>

WY_LOG_TYPE_ERROR <<**
This is the third error
blah - blah - blah
**>>

выход:

WY_LOG_TYPE_ERROR <<**
This is the third error
blah - blah - blah
**>>
0 голосов
/ 28 марта 2011

Возможно, вы ищете \z в соответствии с регулярным выражением, чтобы соответствовать EOF , чтобы соответствовать Концу файла.

 WY_LOG_TYPE_ERROR\s*<<\*\*((.|\n))\\*>>\z

(непроверенные)

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