需要帮助正则表达式

时间:2011-03-28 10:55:44

标签: regex perl

在我的日志文件中,使用开始和结束标记记录条目。如下所示

WY_LOG_TYPE_ERROR<< **
  这是第一个错误   等等 - 等等 **指与GT;

WY_LOG_TYPE_ERROR<< **
  这是第二个错误   等等 - 等等 **指与GT;

WY_LOG_TYPE_ERROR<< **
  这是第三个错误   等等 - 等等 **指与GT;

在任何给定时间,日志文件中都有上述3个条目 我想要一个正则表达式只匹配最后一个条目。

目前我正在使用以下reg-exp:
WY_LOG_TYPE_ERROR \ S * LT;< \ * \ *((| \ n)的*)\ * \ * GT;> $

现在$ 1包含第一个条目的开始标记和最后一个条目的结束标记之间的所有内容 我想要的是最后一个条目的开始和结束标记之间的内容。我不关心其他条目。

任何人都可以修改此reg-exp以满足我的需求。

编辑:我正在使用perl reg-ex

编辑:我需要使用reg-exp,因为我使用SEC进行错误日志处理。

5 个答案:

答案 0 :(得分:2)

为什么在大量字符串匹配是简单的线性搜索时使用正则表达式?

只需使用WY_LOG_TYPE_ERROR

的最后一个子字符串搜索,就可以更简单地解决这个问题

例如,在javascript中(虽然这几乎可以用我能想到的任何语言实现)

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

那有多简单?更不用说更快,因为lastIndexOf从字符串的末尾开始(将扩展为任意大的日志字符串/文件/流),我们不需要构建状态机(即构造正则表达式) )。

答案 1 :(得分:1)

你需要做一个非贪婪的&#34;比赛。默认情况下,*是贪婪的,这意味着它将尽可能匹配。大多数语言使用*?来表示非贪婪或最短的匹配。

答案 2 :(得分:1)

您还可以使用否定前瞻断言它是最后一条日志记录:

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 = "";
}

答案 3 :(得分:0)

根据regex to match EOF,您可能正在寻找\z来匹配文档结尾。

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

(未测试的)

答案 4 :(得分:0)

这是一种方法:

#!/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
**>>