【问题标题】:Parse a call transcript into array of hash - Ruby将调用记录解析为哈希数组 - Ruby
【发布时间】:2021-11-03 19:04:17
【问题描述】:

我正在解析通话记录。成绩单的内容以字符串形式返回,格式如下:

"Operator: Hi, please welcome Bob Smith to the call. Bob Smith: Hello there, thank you for inviting me...Now I will turn the call over to Stacy. Stacy White: Thanks Bob. As he was saying...."

每个新发言者开始发言时没有换行。

我想把上面的字符串变成一个哈希数组。类似于以下内容:

[ { speaker: "Operator",
    content: "Hi, please welcome Bob Smith to the call" },
  { speaker: "Bob Smith",
    content: "Hello there, thank you for inviting me...Now I will turn the call over to Stacy." }, 
  { speaker: "Stacy White",
    content: "Thanks Bob. As he was saying...." }
]

我想我需要使用某种正则表达式来解析它,但不知道如何在花了早上阅读它之后。在这里的任何帮助将不胜感激。

谢谢

更新:

对于可能觉得这很有用的其他人,这是我最终使用以下建议的解决方案得出的结论:

def display_transcript
  transcript_pretty = []
  transcript = self.content
  transcript_split = transcript.split(/\W*([A-Z]\w*\W*\w+):\W*/)[1..-1]
  transcript_split_2d = transcript_split.each_slice(2).to_a
  transcript_split_2d.each do |row|
    blurb = { speaker: row[0], content: row[1]}
    transcript_pretty << blurb
  end

  return transcript_pretty
end

【问题讨论】:

    标签: ruby-on-rails regex text-parsing


    【解决方案1】:

    我可以给你一个表达式,你可以用它来分解字符串。 从那里你可以自己承担,我敢肯定,你不希望我带走实现目标的乐趣,是吗? :>)

    string = "Operator: Hi, please welcome Bob Smith to the call. Bob Smith: Hello there, thank you for inviting me...Now I will turn the call over to Stacy. Stacy White: Thanks Bob. As he was saying...."
    split_up = string.split(/\W*(\w*\W*\w+):\W*/)[1..-1]
    Hash[*split_up]
    # {"Operator"=>"Hi, please welcome Bob Smith to the call", "Bob Smith"=>"Hello there, thank you for inviting me...Now I will turn the call over to Stacy", "Stacy White"=>"Thanks Bob. As he was saying...."}
    

    一些解释:正则表达式查找一个或两个单词(\w*\W*\w+),最后以一个点和一个空格\W* 开头,然后是一个双点,最后是:\W* 后面的空格 此表达式用于拆分数组中的字符串。 结果总是以空字符串开头,因此您可以通过 [1..-1] 摆脱它 接下来,将该 Array 转换为 Hash,第一个元素是键,第二个元素是值,依此类推,直到 Array 结束。

    【讨论】:

    • 谢谢,这非常有帮助。我通常会放下我尝试过的东西,但对编码和正则表达式来说仍然是新的,对我来说就像是随机符号的混搭哈哈。但是经过一些试验和错误以及你的例子,我想我已经掌握了它。根据您的建议,我已经用我最终提出的问题更新了我的问题。再次感谢!
    • 您不妨解释一下String#split 如何处理捕获组。
    【解决方案2】:
    R = /(\S[^:]*):\s*([^:]*[.?!])/
    
    def str_to_hash(str)
      str.gsub(r).with_object({}) { |_,h| h[$1]=$2 }
    end
    
    str = "Operator: Hi, please welcome Bob Smith to the call. Bob Smith: Hello there, thank you for inviting me...Now I will turn the call over to Stacy. Stacy White: Thanks Bob. As he was saying...."
    str_to_hash(str)
      #=> {"Operator"=>"Hi, please welcome Bob Smith to the call.",
      #=>  "Bob Smith"=>"Hello there, thank you for inviting me...Now I will turn the call over to Stacy.",
           "Stacy White"=>"Thanks Bob. As he was saying...."}
    
    str = "Operator: Bob Smith, what's the value?   Bob Smith: $100,000 or so. Stacy? Stacy White: Thanks Bob. I agree...."
    str_to_hash(str)
      #=> {"Operator"=>"Bob Smith, what's the value?",
      #    "Bob Smith"=>"$100,000 or so. Stacy?",
      #    "Stacy White"=>"Thanks Bob. I agree...."}
    

    您可以看到正在运行的正则表达式here

    这使用String#gsub 的形式,它接受一个参数(这里是一个正则表达式)并且没有块,返回一个链接到Enumerator#with_object 的枚举器。1

    我们可以在free-spacing模式下编写正则表达式,使其自文档化。

    R = /
        (           # begin capture group 1
          \S        # match a character other than a whitespace
          [^:]*  # match 0+ characters other than a colon
        )           # end capture group 1
        :           # match a colon
        \s*         # match 0+ whitespaces
        (           # begin capture group 2
          [^:]*     # match 0+ characters other than a colon
          [.?!]     # match a period, question mark or exclamation mark
        )           # end capture group 2
        /x          # free-spacing regex definition mode 
    

    因为[^:]*贪婪 [.?!] 将匹配冒号或字符串结尾之前的最后一个句点、问号或感叹号。

    1 请注意,String#gsub 的这种形式与字符替换无关。它只返回匹配项,这些匹配项由第一个块变量 _ 保存。该块变量使用下划线表示它没有在块中使用。

    【讨论】:

    • @Thefourthbird,当还有一个“ruby”标签时,我现在只做 q 有“regex”标签。我厌倦了那个小组的各个方面。感谢挂在那里。
    • 嗯,你仍然知道你的东西 :-) 祝你好运!
    猜你喜欢
    • 2023-04-03
    • 1970-01-01
    • 2014-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 2020-07-13
    相关资源
    最近更新 更多