首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用Ruby对csv文件中的值求和

如何用Ruby对csv文件中的值求和
EN

Stack Overflow用户
提问于 2019-08-13 05:47:01
回答 1查看 92关注 0票数 1

我有一个包含多个列的Csv文件。第四列有一种我想要解析的格式。下面的字符串str将是文件的一行:

代码语言:javascript
复制
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的值。

输出将为:

代码语言:javascript
复制
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一起。

代码语言:javascript
复制
require 'csv'

CSV.parse(str)

For 4th column do
       //Parse

我如何在Ruby中做到这一点?

谢谢你的帮助

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-13 07:16:59

这个问题的本质是从"108,882,xyz, "后面的字符串部分提取所需的信息,而不是如何解析CSV字符串,因此我将只关注前者。

代码语言:javascript
复制
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

此正则表达式通常按如下方式编写:

代码语言:javascript
复制
/Val1:\{(\d+)\} +Val2:\{(\d+)\} +[^\}]+\} +xTime: +\{(.+?)\}/

请注意,在使用自由空格模式时,如果没有以某种方式保护空格字符,解析器会将它们剥离。有几种方法可以保护它们。我选择对每个空格字符进行转义。自由空格模式的优点是它使正则表达式自文档化。

代码语言:javascript
复制
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"]]

代码语言:javascript
复制
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" 

代码语言:javascript
复制
def convert(arr)
  arr.map(&:to_i).sum
end

代码语言:javascript
复制
convert(val1)
  #=> 8093 
convert(val2)
  #=> 1681 
"%s - %s" % [f,l]
  #=> "2018-11-10 09:56:12 - 2018-11-10 10:13:12:22"

参见String#scan

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57468646

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档