如果可能,执行搜索操作并从其后面的文本中保存一些数据

时间:2014-06-08 19:03:38

标签: ruby regex string full-text-search

有一个包含此文本的文本文档。

---random data---
==String_1==
{{item_1
    | name= name_1 | url=url_1 | email= email_1 | address= |
}}
---random data---

现在,我希望每当遇到String_1时,所有字段(名称,网址,电子邮件和地址)都作为名为item_1的哈希中的字符串。 Ruby代码是首选。

2 个答案:

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