在Ruby数组上匹配文字字符串

时间:2014-10-28 00:15:05

标签: ruby arrays regex string

我创建了一个数组,我希望将它与文件匹配。如果文件不包含数组项,那么我希望将它们附加到文件中。以下是它现在的样子:

data = tasks.map { |d, e| Time.parse(d).strftime("%Y-%m-%d,%H:%M,") + "#{project}" + e.strip }
target = '/Users/username/file.csv'
info = File.read(target)
out = File.open(target, 'a')
data.each { |t| out.write("#{t}\n") if info !~ /(#{t})/ }

然而,在文件评估/#{t}中,如果数组项包含特殊的正则表达式字符,例如“(”或“[”。),那么会产生误报。所以会发生这样的事情,即使它们是已存在于文件中。我该如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

使用Regexp Escapes

您的帖子并未包含实际的语料库,因此无法确定导致问题的原因或数据应该是什么样的。将来,请在您的问题中包含此类信息。

根据经验,动态构造的正则表达式应该是:

  1. 锚定在您的模式中。
  2. 使用Regexp#escape方法转义。
  3. 例如,我可能会像这样重写你的逻辑:

    data.each { |t| out.puts t unless info =~ /#{Regexp.escape t}/ }
    

    样本转换

    只是想知道#escape方法在幕后做了什么,想象一下你的数据是这样的:

    t = 'foo[^bar]'
    #=> "foo[^bar]"
    
    regex = Regexp.escape t
    #=> "foo\\[\\^bar\\]"
    
    t.match /#{regex}/
    #=> #<MatchData "foo[^bar]">
    

    因此#escape方法允许您将字符串与插值的正则表达式文字中包含的相同字符进行匹配。这真的很酷,希望能帮到你。

答案 1 :(得分:2)

如果你不关心模式,为什么要使用正则表达式呢?为什么不使用include?

  

包含? other_str→true或false

     

如果 str 包含给定的字符串或字符,则返回true

所以你可以说:

data.each { |t| out.write("#{t}\n") unless info.include? t

或者您使用index

  

index(substring [,offset])→fixnum或nil
   index(regexp [,offset])→fixnum或nil

     

返回 str 中给定子字符串或模式( regexp )第一次出现的索引。如果找不到,则返回nil

并说

data.each { |t| out.write("#{t}\n") unless info.index t