2

根据 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

谢谢你的帮助!

伊恩

=================================== 更新:继锡芒评论 -

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

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

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

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

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

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

非常感谢

伊恩

4

1 回答 1

4

Why would you want to match anything in a YAML file? Load it into Ruby using the YAML parser, and search it, or modify in memory.

If you want to save the modified file, the YAML parser can emit a Ruby object as YAML, which you then save.

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"

Based on the above definitions, manipulating the data could be done like this:

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

Which outputs:

---
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

There's a reason we have YAML parsers for all the different languages; They make it easy to load and use the data. Take advantage of that tool, and use Ruby to modify the data, and, if needed, write it out again. It would be one huge YAML file before I'd even think of trying to modify it on disk considering it's so easy to do in memory.

Now, the question becomes, how do you search the keys of a hash using a regex?

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

Once you have the ones you want, you can easily modify their contents, substitute them back into the in-memory hash, and write it out.

于 2013-02-11T14:52:52.247 回答