【问题标题】:Create a regular expression to match YAML keys in Ruby创建正则表达式以匹配 Ruby 中的 YAML 键
【发布时间】:2013-01-26 16:14:59
【问题描述】:

基于 YAML 文件中的以下数据,是否可以在 Ruby 中创建一个匹配列表中相应 Group 和 Item 键的正则表达式

源数据

Groups:
    GroupA:
    - item 1
    - item 3
    Group B:
    - itemA
    - item 3
    C:
    - 1
    - item 3

测试字符串:

GroupA item 1     
Group B itemA
c item 1
C 1
GroupA 1

预期匹配组

Match 1:
   1. GroupA
   2. item 1
Match 2:
   1. Group B
   2. itemA
Match 3:
   1. C
   2. 1

感谢您的帮助!

伊恩

=================================== 更新:关注 Tin Mans 评论 -

这里有一些更进一步的背景......

插件内部存在一个包含许多方法的类。每个方法都接收一个字符串,该字符串被解析以确定执行什么操作。在某些方法中,字符串的内容用于后续操作 - 当需要时,使用正则表达式来提取(或匹配)字符串的相关部分。不幸的是,无法控制上游代码来改变这个过程。

在这种情况下,字符串采用“组项目状态”的形式。但是,组和项目名称不一定是单个单词,并且每个组不必包含所有项目。例如

"Group A Item 1"
"c item 1"
"GroupA 1"

因此,需要一种方法来解析输入字符串以获取相应的 Group 和 Item,以便将正确的值传递给更进一步的方法。鉴于该类中的其他类似方法使用正则表达式,并且有一个 YAML 文件包含组 - 项对的最终列表,所以我首先想到的是正则表达式。

但是,我愿意接受更好的方法

非常感谢

伊恩

【问题讨论】:

    标签: ruby regex yaml


    【解决方案1】:

    为什么要匹配 YAML 文件中的任何内容?使用 YAML 解析器将其加载到 Ruby 中,然后在内存中进行搜索或修改。

    如果你想保存修改后的文件,YAML 解析器可以发出一个 Ruby 对象作为 YAML,然后你保存它。

    require 'yaml'
    
    yaml = '
    ---
    Groups:
        GroupA:
        - item 1
        - item 3
        Group B:
        - itemA
        - item 3
        C:
        - 1
        - item 3
    '
    
    yaml = YAML.load(yaml)
    # => {"Groups"=>{"GroupA"=>["item 1", "item 3"], "Group B"=>["itemA", "item 3"], "C"=>[1, "item 3"]}}
    
    yaml['Groups']['GroupA'].first
    # => "item 1"
    
    yaml['Groups']['Group B'][1]
    # => "item 3"
    
    yaml['Groups']['C'].last
    # => "item 3"
    

    根据上述定义,可以这样操作数据:

    yaml = YAML.load(yaml)
    groups = yaml['Groups']
    
    new_group = {
      'groupa_first' => groups['GroupA'].first,
      'groupb_second' => groups['Group B'][1],
      'groupc_last' => groups['C'].last
    }
    yaml['New Group'] = new_group
    
    puts yaml.to_yaml
    

    哪些输出:

    ---
    Groups:
      GroupA:
      - item 1
      - item 3
      Group B:
      - itemA
      - item 3
      C:
      - 1
      - item 3
    New Group:
      groupa_first: item 1
      groupb_second: item 3
      groupc_last: item 3
    

    我们有所有不同语言的 YAML 解析器是有原因的;它们使加载和使用数据变得容易。利用该工具,并使用 Ruby 修改数据,如果需要,再次将其写出。这将是一个巨大的 YAML 文件,我什至会考虑尝试在磁盘上修改它,因为它很容易在内存中完成。

    现在,问题变成了,如何使用正则表达式搜索散列的键?

    yaml['Groups'].select{ |k,v| k[/^Group/] }
    # => {"GroupA"=>["item 1", "item 3"], "Group B"=>["itemA", "item 3"]}
    

    一旦你有了你想要的,你就可以轻松地修改它们的内容,将它们替换回内存中的哈希值,然后写出来。

    【讨论】:

    • 嗨 Tin Man,感谢您的评论,我已经编辑了我的问题以帮助提供更多背景信息。我会很感激任何进一步的cmets。伊恩
    猜你喜欢
    • 2018-03-09
    • 1970-01-01
    • 2013-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-26
    相关资源
    最近更新 更多