2013-07-02 55 views
5

我工作所記錄的服務器之間的文件傳輸的字符串。這些最終必須上傳到數據庫,所以我對它們進行了預處理以檢查錯誤。每個日誌文件條目代表一個傳輸,它們的格式如下:分裂容納空間分隔的「鍵=值」對時的值也可以包含空間

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」之間有空格。有什麼方法可以設計一個正則表達式來解釋所有這些鍵值對嗎?如果沒有正規的表達方式來做到這一點,你能否建議我採取其他方式來處理它?

我的目標是取代那些沒有任何空間(即刪除空格)或下劃線這樣,當我運行加載到數據庫中的腳本,它不會有問題只是在拆分空單。順便說一下,我使用perl來完成所有這些。

+0

可你總是指望這些字段的順序是? –

+0

我建議增加值作爲引號中的字符串,要麼所有的值或者至少包含空白的人。 – 0xCAFEBABE

+0

@DanielGimenez是的。它由服務器記錄。 – shaun

回答

9

您可以通過使用一個lookahead,以確保它們不會以上任一鍵搜索不需要的空格:

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

先行確保有下一個空格字符之前沒有=

那麼可以拆分上的空間。

另外,搭配向右走,你可以使用類似的技術:

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

對於我們重複或者非空格字符或者不以上任一鍵位的值。

Working demo.

如果你的鑰匙總是大寫,您可以用[A-Z]+取代所有\S+在我的代碼。

+0

正則表達式+1。我無法像解決方案一樣簡潔。善於使用否定的空格。 –

+0

非常感謝你,先生!這真的很好。 – shaun