我正在尝试解析一些Microsoft日志记录信息。这些日志来自于所谓的“人类可读”文本的大块,其中的例子可以在Windows Security Blog看到,并且有一个特定的事件我想从我的分析中排除,即“一个操作是在一个对象“当有问题的对象是groupPolicyContainer时。
这是我的正则表达式和测试代码:
my $re = qr/(?ms)EventCode=(4662)[^\d].*Object Type:\s*((?!groupPolicyContainer)\S)*/;
if ($sample1 =~ $re) { print "Matches -- should not have\n"; }
if ($sample2 =~ $re) { print "Matches -- and should have!\n"; }
$sample1
包含短语Object Type: groupPolicyContainer
,$sample2
包含短语Object Type: Key
。 (它们都具有相同的EventCode;这是一个人为的测试用例。)如果查看链接,可以看到围绕两个关键短语“EventCode”和“Object Type”的文本很多。 “对象类型”每个日志条目不会出现多次(在我设计的测试用例中)。
正则表达式说:两者都匹配。我的期望是第一个不应该匹配,因为它包含否定的短语!我试图实现previous Stack Overflow response中显示的代码,但它似乎没有工作;这个例子和我的唯一区别是我的操作是一个多行文件。
我已经尝试过(?ms)
我想到的所有可能的组合!我需要做些什么才能在多行文档中使用它?
答案 0 :(得分:1)
就个人而言 - 我认为你对单一的正则表达式方法有点过分了解。我建议改为 - 将对象解析为散列,然后测试散列的相关键。
正则表达式的问题在于它努力匹配。如果失败,则返回跟踪并寻找其他潜在的匹配点。所以在多行中,可能会跳到下一条记录,寻找匹配的块,特别是如果你有多行贪心匹配。
你可以看到
发生了什么use re 'debug';
这将向您展示正则表达式引擎正在做什么。
但一般来说,我会建议,鉴于你有perl,试图制作胜利的正则表达是不必要的痛苦。
我知道这不是你提出的要求,但希望这能说明我的意思
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
local $/; #set this to your record separator, and you can
#use this with a while loop too!
my %this_object = <DATA> =~ m/^\s*(.*): (.*)$/gm;
print Dumper \%this_object;
if ( $this_object{'Handle ID'} eq '0x178'
and $this_object{'Object Type'} eq 'File' )
{
print "Matches this criteria\n";
}
__DATA__
Subject:
Security ID: LB\administrator
Account Name: administrator
Account Domain: LB
Logon ID: 0x3DE02
Object:
Object Server: Security
Object Type: File
Object Name: C:\asdf\New Text Document.txt
Handle ID: 0x178
Resource Attributes: S:AI
Process Information:
Process ID: 0x113c
Process Name: C:\Windows\System32\notepad.exe
Access Request Information:
Accesses: WriteData (or AddFile)
AppendData (or AddSubdirectory or CreatePipeInstance)
Access Mask: 0x6
打印:
$VAR1 = {
'Logon ID' => '0x3DE02',
'Process ID' => '0x113c',
'Process Name' => 'C:\\Windows\\System32\\notepad.exe',
'Resource Attributes' => 'S:AI',
'Account Domain' => 'LB',
'Accesses' => 'WriteData (or AddFile)',
'Security ID' => 'LB\\administrator',
'Access Mask' => '0x6',
'Object Type' => 'File',
'Object Name' => 'C:\\asdf\\New Text Document.txt',
'Object Server' => 'Security',
'Account Name' => 'administrator',
'Handle ID' => '0x178'
};
Matches this criteria
但是,如果这太“过分”,那么这又怎么样呢?:
if ( $thing =~ m/EventCode: 4666/
and not $thing =~ m/groupPolicyContainer/ ) {
print "Matches this criteria\n";
}
保存必须找出负正则表达式匹配,并且可能也更有效,因为它不需要回溯。