Regex DNS应答的正则表达式解析

Regex DNS应答的正则表达式解析,regex,perl,sed,Regex,Perl,Sed,我想分析以下几行 8.8.19.12.53>125.15.15.9.40583:[udp sum ok]62639问:A?微软网站。6/5/9 mp.microsoft.com。CNAME.mp.microsoft.com.c.footprint.net.,mp.microsoft.com.c.footprint.net。A 8.250.143.254,mp.microsoft.com.c.footprint.net。A 8.250.157.254 ns:c.footprint.net。NS d

我想分析以下几行

8.8.19.12.53>125.15.15.9.40583:[udp sum ok]62639问:A?微软网站。6/5/9 mp.microsoft.com。CNAME.mp.microsoft.com.c.footprint.net.,mp.microsoft.com.c.footprint.net。A 8.250.143.254,mp.microsoft.com.c.footprint.net。A 8.250.157.254 ns:c.footprint.net。NS d.NS.c.footprint.net。ar:d.ns.c.footprint.net。A 4.26.235.155(439)
8.8.19.12.53>125.15.15.9.42091:[udp总和正常]46555问:A?www.toto.net。1/0/0 www.toto.net。A 120.33.1.11(47)
并获得以下输出

125.15.15.9 mp.microsoft.com A 8.250.143.254 A 8.250.157.254
125.15.15.9 www.toto.net A 120.33.1.11
我成功地用命令解析了前两个字段

sed-Eun的/[^>]+>([0-9.]+)\[0-9]+:.+q:A\?([a-z0-9.-]+)\。([^::]+)./\1:\2:\3/pg
`

但我无法获得已解析的IP(A xx.xx.xx.xx)。事实上,可能有几个

是否可以使用sed或Perl获得这样的输出

编辑: 正如我在注释中添加的,解析一个更大的输入样本,我还需要在输出中丢弃几行。这条线的特点是:

  • A记录的编号(“A xx.xx.xx.xx”)不为空
  • 或者该行不能包含
    NXDomain\*?-
我成功地满足了第一种新需求,但第二种需求却没有

在@ikegami回复之后,我的尝试如下:

perl-nle'
我的$field\u value\u re=qr/(?![^\s:++:(?!\s))\s++(?:(?!\s++[^\s:++:(?!\s))\s++\s++*+/x;
我的($id,$rest)=/^\s+([^:::++):\s++$field\u value\u re(.*)/sx
或下一步;
my($ip)=$id=~/^\S++\S++\S++++\S++([^\S\.]++\.[^\S\.]++\.[^\S\.]++\.[^\S\.]++)\.[^\S\.]+\z/x
或下一步;
我的%fields=$rest=~/\G\s++([^\s:++):(?!\s)\s++($field\u value\u re)/gsx;
我的($query,$answers)=$fields{q}=~/^A\\s++(\s++)\s++\s++\s++++(.*)/sx
或下一步;
$query=~s/\.\z/;
my@answers=拆分(/\s*+,\s*+/,$answers);
我的($afield)=加入“”,映射{/^\S++\S++A\S++(\S++)/}@answers;
如果(长度($afield)!=0)
{
打印$ip、$query、$AFELD;
}
'dns.sample

这将按照您对示例数据的要求执行

我首先构建一个正则表达式模式
$url\u re
,它匹配数字url,以使下面的代码更加简洁。然后,我搜索紧跟在
之后的第一个URL,紧跟在
A?
之后的命名URL,以及后面以
A
开头的所有URL

它们都存储在数组
@url
中并打印出来

使用严格;
使用“全部”警告;
使用5.010;
我的$url\u re=qr/(?:\d+\){3}\d+/;
而(){
我的@url=(/>\s+($url\u re)/,/A\?\s+([-\w.]+\w)/,/(A\s+$url\u re)/g);
说“@url”;
}
__资料__
8.8.19.12.53>125.15.15.9.40583:[udp总和正常]62639问:A?微软网站。6/5/9 mp.microsoft.com。CNAME.mp.microsoft.com.c.footprint.net.,mp.microsoft.com.c.footprint.net。A 8.250.143.254,mp.microsoft.com.c.footprint.net。A 8.250.157.254 ns:c.footprint.net。NS d.NS.c.footprint.net。ar:d.ns.c.footprint.net。A 4.26.235.155(439)
8.8.19.12.53>125.15.15.9.42091:[udp总和正常]46555问:A?www.toto.net。1/0/0 www.toto.net。A 120.33.1.11(47)
输出
125.15.15.9 mp.microsoft.com A 8.250.143.254 A 8.250.157.254 A 4.26.235.155
125.15.15.9 www.toto.net A 120.33.1.11

每一行的格式如下

{"id" with spaces}: {stuff} [ {key}: {stuff} ]*
A? {word} {word} {ns_return} [, {ns_return} ]*
您似乎对“id”内的信息以及名为
q
的字段内的信息感兴趣。
q
字段的值的形式如下

{"id" with spaces}: {stuff} [ {key}: {stuff} ]*
A? {word} {word} {ns_return} [, {ns_return} ]*
这里有一个处理上述格式的健壮解决方案

perl -nle'
   my $field_value_re = qr/(?![^\s:]++:(?!\S)) \S++ (?: (?! \s++ [^\s:]++:(?!\S) ) \s++ \S++ )*+/x;

   my ($id, $id_val, $rest) = /^ ( [^:]++ ) : \s++ ( $field_value_re ) ( .* ) /sx
      or next;

   next if $id_val =~ /\bNXDomain\b/;

   my ($ip) = $id =~ /^ \S++ \s++ \S++ \s++ ( [^\s\.]++\.[^\s\.]++\.[^\s\.]++\.[^\s\.]++ )\.[^\s\.]++ \z /x
      or next;

   my %fields = $rest =~ /\G \s++ ( [^\s:]++ ) :(?!\S) \s++ ( $field_value_re ) /gsx;

   my ($query, $answers) = $fields{q} =~ /^ A\? \s++ ( \S++ ) \s++ \S++ \s++ ( .* ) /sx
      or next;

   $query =~ s/\.\z//;

   my @answers =
      map { /^\S++\s++A\s++(\S++)/ }
         split(/\s*+,\s*+/, $answers);

   next if !@answers;

   print join " ", $ip, $query, map { "A $_" } @answers;
' log
125.15.15.9 mp.microsoft.com A 8.250.143.254 A 8.250.157.254
125.15.15.9 www.toto.net A 120.33.1.11

通过使用
map
函数以某种非常规的方式忽略
q:

perl -lne 'print join qq/\t/, m/> ([\d\.]+)\./, map {/A\? ([^\s]+)\./, /(A [\d\.]+)/g} / q:([^:]+)/' log.txt

我编辑了你的问题,试图理解它。输入的数据真的只有两行吗?我的投票结果是countermeasures@Borodin. 谢谢你的编辑。从流中提取所提供的传入数据。这些被选为输入的代表性示例。@ikegami好的,我将第二个和第三个正则表达式限制在
q:
字段中,正如您在回答中指出的那样。它很难看,但应该可以工作。与所需输出的区别在于/(A[\d\.]+)/g在匹配一个潜在的“ns:”后应该停止field@vera是的,固定的now@vera,为什么要奖励脆弱性和缺乏可维护性?!(更糟糕的是,OP已经想要两个改变!)我并没有说这是一个更好的答案,这只是众多可能答案中的一个。我遵从@ikegami关于什么是脆弱的和可维护的我只是在一个更大的输入样本(500k行)上运行,我发现了一个不包含在描述中的案例。是否可以放弃与
NXDomain\*?-”匹配的行?q:
?很抱歉,我又添加了一个案例:我还想放弃没有返回IP记录的行(A xx.xx.xx.xx)。我知道这在后处理处理(
grep-v
awk
)中是可能的。我编写了代码,这样做很容易,而你宣布你特别投票给了某个人,因为他让你很难做到。那么,你自己都不想做改变吗?那太侮辱人了,我不是故意侮辱你的。我对其他回复投了更高的票,因为它们满足了我最初的需求。然而,我选择了你的回复作为我脚本的来源,因为与其他回复相比,这是非常清楚的,即使我不了解所有细节。这就是为什么我在你的回复中增加了两个问题(评论),而不是在所有回复中。此外,您的代码对您来说可能很简单,尽管我不是这样。我尝试了几个小时(现在仍在尝试)修改您的代码,以满足我对regex101的所有需求,但没有成功。事实上,我并不熟悉如此复杂的正则表达式;我说改变很简单(因为我已经