2016-05-03 1 views
1

入力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]'                
     ];   

したがって、返される配列の5番目の要素が必要です。

0

私はこのregex demo作成:私の答えは、あなたが一致するURLは、常にHTTPステータスコードが続くことを前提としている

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

を。

それは、我々はまた、(このSO postのように)書くことができますHTTPステータスコードですので:

\[[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デモで非貪欲型の限定記号です。

+2

私はあなたのソリューションが好きです。キャプチャグループを含める必要があります: '/ \ [([^ \]] +)\]/g' – eballes