2016-05-03 89 views
1

輸入如何提取UNIX路徑在Perl

[security] [client 198.66.91.7] [domain testphp.example.com] [200] [/apache/20160503/20160503-0636/[email protected]] (null) 

所需的輸出

/apache/20160503/20160503-0636/[email protected] 

這裏是我迄今爲止

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

我的Perl代碼。

#!/usr/bin/perl 
use feature 'say'; 

$txt='[modsecurity] [client 199.66.91.7] [domain testphp.vulnweb.com] [200] [/apache/20160503/20160503-0636/[email protected]] (null)'; 


$re=''.*?\[.*?\].*?\[.*?\].*?\[.*?\].*?\[.*?\].*?\[(.*?)\]''; 

if ($txt =~ m/$re/is) 
{ 
    $sbraces1=$1; 
    say $1; 
} 

輸出

/apache/20160503/20160503-0636/[email protected] 

我覺得我的正則表達式是凌亂?也許另一種方式?

感謝

+2

您應該使用拆分方法。 –

+1

您的評論應該是一個答案 – Deano

+0

@Deano我添加了答案。 – AKS

回答

3

我會用一個分裂太...或比您正在使用一個更一般的正則表達式:

#!/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/[email protected]] (null)'; 

my @fields = $data =~ /(?:\[(.*?)\])+/g; 

print Dumper(\@fields); 

你得到的輸出是:

$VAR1 = [ 
      'security', 
      'client 198.66.91.7', 
      'domain testphp.example.com', 
      '200',                                
      '/apache/20160503/20160503-0636/[email protected]'                
     ];   

所以返回數組的第五個元素就是你想要的。

0

我創造了這個regex demo

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

我的答案是基於這樣的假設,你想匹配的網址將始終跟着一個HTTP狀態代碼。

既然是HTTP狀態代碼我們也可以寫成(如本SO post):

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

使用字符類的否定。因爲它的表現比非貪婪的斷言更好。

my $txt = '[security] [client 198.66.91.7] [domain testphp.example.com] [200] [/apache/20160503/20160503-0636/[email protected]] (null)'; 

my @array = $txt =~ /\[([^\]]+)\]/g; 

print "@array\n"; 

Here演示字符類否定。

Here demo for non greedy quantifier。

+2

我喜歡你的解決方案。您應該包含捕獲組:'/ \ [([^ \]] +)\]/g' – eballes