1

我有一个关于正则表达式问题的简单问题。

给定以下示例字符串:

Apr 2 13:42:32 sandbox izxp[12000]: Received disconnect from 10.11.106.14: 10: disconnected by user

我需要将此字符串分成 4 个不同的字符串。如您所见:日期(Apr 2)、时间(13:42:32)、服务器名称(sandbox)和其他数据(izxp[12000]: Received disconnect from 10.11.106.14: 10: disconnected by user)。

之后这些将是变量值。

我会很高兴有人可以帮助我!

谢谢!

4

3 回答 3

6

split使用此任务要容易一些。

my ($date1, $date2, $time, $host, $data) = split(' ', $str, 5);
my $date = "$date1 $date2";
于 2012-05-15T12:27:12.820 回答
1

对于这类事情,我总是使用我所谓的“扫描模式”。日期的格式很简单:

/((?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+\d+)

当时的表达并不难

/(\d\d:\d\d:\d\d)/

一旦你把它排除在外,我认为像这样指定服务器就很容易了:

/(\w+)/

下一部分就是其他所有内容,因此该模式可以连接在一起:

/((?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+\d+)\s+(\d\d:\d\d:\d\d)\s+(\w+)\s+(.*)/

您可以通过以下表达式将该数据存储在 Perl 中:

my ( $date, $time, $host, $desc ) 
    = $str =~ m/((?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+\d+)
                \s+(\d\d:\d\d:\d\d)\s+(\w+)\s+(.*)
               /x
    ;
于 2012-05-15T13:08:26.840 回答
0

请注意,拆分或准备好的正则表达式之间的性能比较(在下面的输出中:re1 来自 Axeman 并且 re2 简化为/(\S+ \S+) (\S+) (\S+) (.*)/)确认拆分是获胜的,但差异很小,您甚至不会在解析不到一百万行时注意到它。Axeman 正则表达式可以进一步改进,以帮助您证明输入的有效性,这是非常重要的事情。

1000 万次迭代比较:

        Rate  re1  re2  spl
re1 250000/s   -- -28% -57%
re2 344828/s  38%   -- -41%
spl 584795/s 134%  70%   --

以下是古代 Core Duo 上 1 亿次调用的概要:

re1: 40 wallclock secs (39.84usr+0.00sys=39.84CPU) @ 251004.02/s (n=10000000)
re2: 29 wallclock secs (29.04usr+0.01sys=29.05CPU) @ 344234.08/s (n=10000000)
spl: 18 wallclock secs (16.77usr+0.00sys=16.77CPU) @ 596302.92/s (n=10000000)

从这么多的记录来看,它看起来很重要。但是,如果您要在某处检查其余数据字符串的有效性,则最好在解析阶段检查一次。

于 2012-06-13T18:54:13.000 回答