1

正規表現の問題について簡単な質問があります。

次の例の文字列が与えられます。

Apr 2 13:42:32 sandbox izxp[12000]: Received disconnect from 10.11.106.14: 10: disconnected by user

この文字列を 4 つの異なる文字列に分ける必要があります。ご覧のとおり、日付 ( Apr 2)、時刻 ( 13:42:32)、サーバー名 ( sandbox)、およびその他のデータ ( izxp[12000]: Received disconnect from 10.11.106.14: 10: disconnected by user)。

これらは後で変数値になります。

誰かが私を助けてくれることをとても嬉しく思います!

どうも!

4

3 に答える 3

6

splitこのタスクには少し使いやすいです。

my ($date1, $date2, $time, $host, $data) = split(' ', $str, 5);
my $date = "$date1 $date2";
于 2012-05-15T12:27:12.820 に答える
1

私は常に、この種のことに対して「スキャン パターン」と呼んでいるものを使用します。日付の形式は非常に簡単です。

/((?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+\d+)

時間の表現はそれほど難しくありません

/(\d\d:\d\d:\d\d)/

それが終わったら、次のようにサーバーを指定するのは簡単だと思います:

/(\w+)/

次の部分は他のすべてなので、パターンは次のように連結できます。

/((?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+\d+)\s+(\d\d:\d\d:\d\d)\s+(\w+)\s+(.*)/

そして、次の式でそのデータを Perl に保存できます。

my ( $date, $time, $host, $desc ) 
    = $str =~ m/((?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+\d+)
                \s+(\d\d:\d\d:\d\d)\s+(\w+)\s+(.*)
               /x
    ;
于 2012-05-15T13:08:26.840 に答える
0

分割または準備された正規表現のパフォーマンス比較 (以下の出力: re1 は Axeman からのもので、re2 は のように単純化されています/(\S+ \S+) (\S+) (\S+) (.*)/) は、分割が勝っていることを確認しますが、違いはわずかであり、解析された 100 万行未満では気付かないことさえあります。Axeman 正規表現をさらに改善して、入力の有効性を証明できるようにすることができます。これは非常に重要なことです。

10mln 反復の比較:

        Rate  re1  re2  spl
re1 250000/s   -- -28% -57%
re2 344828/s  38%   -- -41%
spl 584795/s 134%  70%   --

古い Core Duo での 1 億回の通話の概要は次のとおりです。

re1: 40 wallclock secs (39.84usr+0.00sys=39.84CPU) @ 251004.02/s (n=10000000)
re2: 29 wallclock secs (29.04usr+0.01sys=29.05CPU) @ 344234.08/s (n=10000000)
spl: 18 wallclock secs (16.77usr+0.00sys=16.77CPU) @ 596302.92/s (n=10000000)

この量のレコードでは重要に見えます。ただし、残りのデータ文字列の有効性をどこかで確認する場合は、解析段階で一度確認することをお勧めします。

于 2012-06-13T18:54:13.000 に答える