2016-03-01 43 views
0

如果在Ruby設置中已經提出了這個問題,我表示歉意 - 我在發帖之前檢查過,但要非常誠實地說,這已經是很漫長的一天了,如果我錯過了顯而易見的事件,我提前致歉!Ruby - 將多行製表符分隔的字符串解析爲一個數組數組

我有以下字符串,其中包含系統中安裝的軟件包列表,出於某種原因,我最難解析它。我知道在Ruby中做這件事必須是一種直接的方式,但我一直在做。

我想解析下面的多行,製表符分隔的字符串到數組中,然後我可以用each_with_index循環每個數組元素,並將HTML代碼吐出到我的Rails應用程序中。

str = 'Product and/or Software Full Name 5242  [version 6.5.24]  [Installed on: 12/31/2015] 

Product and/or Software Full Name 5426  [version 22.4]  [Installed on: 06/11/2013] 

Product and/or Software Full Name 2451  [version 1.63]  [Installed on: 12/17/2015] 

Product and/or Software Full Name 5225  [version 43.22.51]  [Installed on: 11/15/2011] 

Product and/or Software Full Name 2420  [version 43.51-r2]  [Installed on: 12/31/2015]' 

最終的結果將是一個數組的數組具有5個元素,像這樣:

[[ 「產品和/或軟件的全名5245」],[ 「版本24年5月6日」] , [「Installed on:12/31/2015」],[「產品和/或軟件全名5426」],[「版本22.4」],[「安裝日期:2013年6月11日」],[「產品和/或軟件全名2451「],[」版本1.63「],[」安裝於:2015年12月17日「]]

請注意:爲簡潔起見,

我寧願從'版本'和'安裝'中去掉方括號,但是如果不能輕易地將它們烘焙到答案中,我可以單獨使用gsub來做到這一點。

最後一件事情是,對於多行字符串中的每一行都不會總是有一個'Installed on'條目,因此在適用的情況下,答案將需要考慮。

回答

1

這應該這樣做:

expr = /(.+?)\s+\[([^\]]+)\](?:\s+\[([^\]]+)\])?/ 
str.scan(expr) 

表達其實是那麼複雜了很多比它的外觀。它看起來很複雜,因爲我們匹配的方括號必須被轉義,並且還使用字符類,它們以正則表達式語言的方括號括起來。它們一起增加了很多噪音。

這是分裂:

expr =/
    (.+?) # Capture #1: Any characters (non-greedy) 

    \s+ # Whitespace 
    \[  # Literal '[' 
    (  # Capture #2: 
     [^\]]+ # One or more characters that aren't ']' 
    ) 
    \]  # Literal ']' 

    (?: # Non-capturing group 
    \s+ # Whitespace 
    \[  # Literal '[' 
     ([^\]]+) # Capture #3 (same as #2) 
    \]  # Literal ']' 
)?  # Preceding group is optional 
/x 

正如你所看到的,第三部分是相同的第二部分,但它是在一個非捕獲組後面是?,使之選。

值得注意的是,這可能會失敗,例如,產品名稱包含方括號。如果這是一個可能性,一個可能的解決方案是包括在比賽中versionInstalled文本,例如:

expr = /(.+?)\s+\[(version [^\]]+)\](?:\s+\[(Installed [^\]]+)\])?/ 

附:下面是一個使用String#split,而不是一個解決方案:

expr = /\]?\s+\[|\]$/ 
res = str.each_line.map {|ln| ln.strip.split(expr) } 
     .reject {|arr| arr.empty? } 

如果你在你的產品名稱,括號,這裏可能的解決方法是指定的部分,例如之間空間的最小數目:

expr = /\]?\s{3,}\[|\]$/ 

......這當然取決於產品名稱永遠不會超過三個連續空格。

+0

究竟是什麼!我很好奇這是如何工作的。我稍後會檢查你的答案,並非常感謝你的跟進! –

+0

@KurtW我編輯了我的答案,包括解釋和替代解決方案。 –

+0

感謝喬丹包括這兩個例子。謝天謝地,我一直在閱讀正則表達式,所以這大部分都是有道理的,但我更喜歡避免使用正則表達式,以便有利於循環等。我感謝您添加使用String#split的版本。產品名稱(例如)中是否包含[String] Split'替代品?我現在用我的數據測試一下,然後很快回來。 –