如何在perl中提取unix路径



输入

[security] [client 198.66.91.7] [domain testphp.example.com] [200] [/apache/20160503/20160503-0636/20160503-063628-Vyh-LH8AAAEAAE6zC@AAAAAD] (null)

所需输出

/apache/20160503/20160503-0636/20160503-063628-Vyh-LH8AAAEAAE6zC@AAAAAD

这是我到目前为止的

'.*?[.*?].*?[.*?].*?[.*?].*?[.*?].*?[(.*?)]'

我的Perl代码。

#!/usr/bin/perl
use feature 'say';
$txt='[modsecurity] [client 199.66.91.7] [domain testphp.vulnweb.com] [200] [/apache/20160503/20160503-0636/20160503-063628-Vyh-LH8AAAEAAE6zC@AAAAAD] (null)';

$re=''.*?[.*?].*?[.*?].*?[.*?].*?[.*?].*?[(.*?)]'';
if ($txt =~ m/$re/is)
{
    $sbraces1=$1;
    say $1; 
}

输出

/apache/20160503/20160503-0636/20160503-063628-Vyh-LH8AAAEAAE6zC@AAAAAD

我觉得我的正则表达式很乱?也许换一种方式?

感谢

我也会使用拆分。。。或者比您使用的正则表达式更通用的正则表达式:

#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
my $data = '[security] [client 198.66.91.7] [domain testphp.example.com] [200] [/apache/20160503/20160503-0636/20160503-063628-Vyh-LH8AAAEAAE6zC@AAAAAD] (null)';
my @fields = $data =~ /(?:[(.*?)])+/g;
print Dumper(@fields);

你得到的输出是:

$VAR1 = [
          'security',
          'client 198.66.91.7',
          'domain testphp.example.com',
          '200',                                                                                                                               
          '/apache/20160503/20160503-0636/20160503-063628-Vyh-LH8AAAEAAE6zC@AAAAAD'                                                            
        ];         

因此,返回数组的第五个元素就是您想要的。

使用字符类否定。因为它的性能比非贪婪断言要好。

my $txt = '[security] [client 198.66.91.7] [domain testphp.example.com] [200] [/apache/20160503/20160503-0636/20160503-063628-Vyh-LH8AAAEAAE6zC@AAAAAD] (null)';
my @array = $txt =~ /[([^]]+)]/g;
print "@arrayn";

这里是角色类否定的演示。

这里是非贪婪量词的演示。

我创建了这个regex演示:

[d{3}]s+[(S+)]

我的回答是基于这样一种假设,即您想要匹配的url后面总是紧跟着HTTP状态代码。

由于它是HTTP状态代码,我们也可以写(如在这篇SO文章中):

[[1-5][0-9]{2}]s+[(S+)]

最新更新