我有一个包含几列的 csv 文件。第 4 列具有我要解析的格式。下面的字符串str
将是文件的一行:
str = "108,882,xyz, { Abc:{-} Val1:{6845} Val2:{653} llsh:{0} xTime: {2018-11-10 09:56:12} Yub:{Rtv} Val1:{807} Val2:{153} llsh:{0} xTime: {2018-11-10 09:59:05}A Wbc:{57} Val1:{441} Val2:{875} llsh:{0} xTime: {2018-11-10 10:13:12:22}"
对于第 4 列,我想对字符串中存在的所有 Val1 和 Val2 求和,并将第一个和最后一个日期显示为新列。如果 Val1 和 Val2 只出现一次,那么总和要做,输出将是 Val1、Val2 和 xTime 的值。
输出将是:
Col1, Col2, Col3, Val1, Val2 , xTime
108, 882, xyz, 8093, 16821, 2018-11-10 09:56:12 - 2018-11-10 10:13:12:22
我正在尝试使用CSV.parse。
require 'csv'
CSV.parse(str)
For 4th column do
//Parse
如何在 Ruby 中执行此操作?
感谢您的任何帮助
这个问题的本质是从"108,882,xyz, "
后面的字符串部分中提取所需的信息,而不是如何解析 CSV 字符串,因此我将注意力限制在前者上。
r = /
Val1:{ # match string
(d+) # match > 0 digits in capture group 1
} +Val2:{ # match string
(d+) # match > 0 digits in capture group 2
} +[^}]+} +xTime: +{ # match string
(.+?) # match > 0 characters lazily in capture group 3
} # match string
/x # free-spacing regex definition mode
此正则表达式通常编写如下:
/Val1:{(d+)} +Val2:{(d+)} +[^}]+} +xTime: +{(.+?)}/
请注意,使用自由间距模式时,如果空间字符未以某种方式受到保护,则解析器将去除它们。有几种方法可以保护它们。我选择转义每个空格字符。自由间距模式的优点是它使正则表达式自文档化。
a = str.scan(r)
#=> [["6845", "653", "2018-11-10 09:56:12"],
# [ "807", "153", "2018-11-10 09:59:05"],
# [ "441", "875", "2018-11-10 10:13:12:22"]]
val1, val2, (f,*,l) = a.transpose
#=> [["6845", "807", "441"],
# [ "653", "153", "875"],
# ["2018-11-10 09:56:12", "2018-11-10 09:59:05", "2018-11-10 10:13:12:22"]]
val1
#=> ["6845", "807", "441"]
val2
#=> ["653", "153", "875"]
f #=> "2018-11-10 09:56:12"
l #=> "2018-11-10 10:13:12:22"
def convert(arr)
arr.map(&:to_i).sum
end
convert(val1)
#=> 8093
convert(val2)
#=> 1681
"%s - %s" % [f,l]
#=> "2018-11-10 09:56:12 - 2018-11-10 10:13:12:22"
请参阅字符串#扫描。