有一个包含此文本的文本文档。
---random data---
==String_1==
{{item_1
| name= name_1 | url=url_1 | email= email_1 | address= |
}}
---random data---
现在,我希望每当遇到String_1时,所有字段(名称,网址,电子邮件和地址)都作为名为item_1的哈希中的字符串。 Ruby代码是首选。
答案 0 :(得分:0)
使用此模式,您可以提取命名捕获内所需的所有值:
/(?: ==String_1== \s+ {{ (?<name> \S+ ) | (?!\A)\G ) # entry point
\s* \| \s*
(?<key> [^\s=]+ ) \s* = \s*
(?<value> [^|}]+? ) (?=\s*[|}]) # the lookahead is used to enforce the lazy
# quantifier to take all the value until an
# optional trailing space before a pipe or a
# closing curly bracket
/x
这是一个通用模式,可能不是最适合您的具体情况,但您可以自由地调整它或使用它来构建您自己的想法。
答案 1 :(得分:0)
这应该这样做,虽然我不太明白你想要将结果保存在名为item1
的哈希中的含义。我已将结果保存在一系列哈希中。我认为你可以根据自己的要求进行调整。 (我为水平滚动道歉 - 我尽量避免使用它。)
<强>代码强>
KEYS = %w{ name url email address }
def pull_vals(fname)
enum = File.readlines(fname).to_enum
arr = []
r = /\s*\|\s*name=\s*(\S*)\s*\|\s*url=\s*(\S*)\s*\|\s*email=\s*(\S*)\s*\|\s*address=\s*(\S*)\s*\|/
loop do
next unless enum.next =~ /==String_1==/
enum.next
arr << KEYS.zip(enum.next.scan(r).flatten(1)).to_h
end
arr
end
示例强>
text =<<_
---random data---
==String_1==
{{item_1
| name= name_1 | url=url_1 | email= email_1 | address= |
}}
---random data---
==String_1==
{{item_2
| name= name_2 | url=url_2 | email= email_2 | address= home |
}}
_
FNAME = "my_file"
File.write(FNAME, text)
pull_vals(FNAME)
#=> [{"name"=>"name_1", "url"=>"url_1", "email"=>"email_1", "address"=>""},
# {"name"=>"name_2", "url"=>"url_2", "email"=>"email_2", "address"=>"home"}]
当在这种情况下,正则表达式模式是重复的时,最简单的方法是让它适用于字符串的一部分,然后使用一些代码来形成正则表达式:
Regexp.new (KEYS.map {|str| "\\s*\\|\\s*#{str}=\\s*(\\S*)"} << "\\s*\\|").join