我很抱歉,如果已经在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"],["版本6.5.24"], ["安装于:2015年12月31日"],["产品和/或软件全名5426"],["版本22.4"],[ "安装于:2013年6月11日"],["产品和/或软件全名2451"],["版本1.63"],[& #34;安装于:2015年12月17日"]]
请注意:为简洁起见,仅显示5个阵列中的3个
我更愿意从“版本”和“版本”中删除括号。和'安装在'但如果不能轻易地将其解释为答案,我可以单独使用gsub。
最后一件事是,不会总是安装在'多行字符串中每一行的条目,因此答案需要考虑到这一点。
答案 0 :(得分: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
如您所见,第三部分与第二部分完全相同,只是在非捕获组中跟随?
使其成为可选项。
值得注意的是,如果可能的话,这可能会失败,例如产品名称包含方括号。如果这是可能的,一个可能的解决方案是在匹配中包含version
和Installed
文本,例如:
expr = /(.+?)\s+\[(version [^\]]+)\](?:\s+\[(Installed [^\]]+)\])?/
P.S。这是一个使用String#split
代替的解决方案:
expr = /\]?\s+\[|\]$/
res = str.each_line.map {|ln| ln.strip.split(expr) }
.reject {|arr| arr.empty? }
如果产品名称中包含括号,则此处可能的解决方法是指定部件之间的最小间距数,例如:
expr = /\]?\s{3,}\[|\]$/
......当然,这取决于产品名称从不超过三个连续的空格。