2013-07-02 6 views
5

ログされているサーバー間のファイル転送を行っています。これらは最終的にデータベースにアップロードする必要があるため、エラーをチェックするためにそれらを前処理しています。各ログファイルエントリは転送を表し、次の形式をとります。スペースで区切られた "key = value"のペアを含む文字列を分割する場合、値にもスペースを含めることができます

key1=value1 key2=value2 

合計16フィールドです。誰かがスペースを含む名前のファイルを転送する場合を除いて、ほとんどの転送は問題ありません。これは、私のperlスクリプト内のスペース上の分割を呼び出すだけで、私の処理が乱れることになります。例:

DATE=20130411140806.384553 HOST=somehost PROG=someserver NL.EVNT=FTP_INFO START=20130411140806.384109 USER=someuser FILE=/extended_path/Wallpapers Folder.ico BUFFER=98720 BLOCK=262144 NBYTES=0 VOLUME=/ STREAMS=2 STRIPES=1 DEST=[0.0.0.0] TYPE=STOR CODE=226 

これは、「壁紙」と「Folder.ico」の間にスペースがある場合の1つの例です。それを説明し、それらのすべてのキーと値のペアを分割できる正規表現を設計する方法はありますか?それを行うための正規表現の方法がない場合は、それを処理するための他の方法を提案できますか?

私の目的は、これらのスペースを空白(空白を取り除く)またはアンダースコアに置き換えることで、データベースに読み込むためのスクリプトを実行するときに単一のスペースで分割するだけで問題にならないようにすることです。私はperlを使ってこのすべてをやっています。

あなたは、彼らが鍵をprecedしていないことを保証 lookaheadを使用することにより、不要なスペースを検索することができます
+0

あなたはいつもそれらのフィールドがその順序にある​​ことを期待できますか? –

+0

値を引用符付きの文字列として追加することをお勧めします。すべての値または少なくとも空白を含む文字列のいずれかです。 – 0xCAFEBABE

+0

@DanielGimenezはい。これはサーバーによって記録されます。 – shaun

答えて

9

$input =~ s/[ ](?!\S+=)/_/g; 

先読みは、次の空白文字の前に何=がないことを確認します。

次に、スペースで分割することができます。私たちは鍵をprecedない非空白文字またはスペースのいずれかを繰り返し値について

while ($input =~ m/(\S+)=((?:\S|[ ](?!\S+=))+)/g) 
{ 
    # $1 is the key 
    # $2 is the value 
} 

また、すぐに一致させるために、あなたは同様の手法を使用することができます。

Working demo.

あなたの鍵は、常に大文字であれば、あなたは[A-Z]+で私のコード内のすべての\S+を置き換えることができます。

+0

+1私は解決策ほど簡潔ではありませんでした。否定された空白をうまく使います。 –

+0

ありがとうございました!それは本当にうまくいった。 – shaun

関連する問題