与ruby中的sub相反

时间:2016-01-26 15:24:52

标签: ruby regex

我想替换与我的过滤器不匹配的内容(或删除它)。 我认为完美的描述将是一个相反的子。我在文档中找不到类似的东西,我不知道如何反转正则表达式,但我认为方法可能更方便。

它是如何工作的一个例子(我刚刚更改了单词以使其更清晰)

"bird.cats.dogs".opposite_sub(/(dogs|cats)\.(dogs|cats)/, '') 
#"cats.dogs"

我希望这很容易理解。 提前谢谢。

3 个答案:

答案 0 :(得分:4)

String#[]可以将正则表达式作为参数:

▶ "bird.cats.dogs"[/(dogs|cats)\.(dogs|cats)/]
#⇒ "cats.dogs"

对于多个匹配,可以使用String#scan

▶ "bird.cats.dogs.bird.cats.dogs".scan /(?:dogs|cats)\.(?:dogs|cats)/
#⇒ ["cats.dogs", "cats.dogs"]

答案 1 :(得分:3)

所以你想提取与正则表达式匹配的部分吗?

您可以使用String#slice,例如:

"bird.cats.dogs".slice(/(dogs|cats)\.(dogs|cats)/)
#=> "cats.dogs"

String#[]也是如此。

"bird.cats.dogs"[/(dogs|cats)\.(dogs|cats)/]
#=> "cats.dogs"

答案 2 :(得分:1)

您不能拥有单个替换字符串,因为字符串中与正则表达式匹配的部分可能不在字符串的开头或结尾,在这种情况下,不清楚替换字符串是在匹配字符串之前还是之后。因此,我写了两个替换字符串,一个用于预匹配,另一个用于post_match。我已经把它作为String类的一个方法,就像你要求的那样(尽管我给这个方法一个不太完美的名字:-))

class String
  def replace_non_matching(regex, replace_before, replace_after)
    first, match, last = partition(regex)
    replace_before + match + replace_after
  end
end

r = /(dogs|cats)\.(dogs|cats)/

"birds.cats.dogs.pigs".replace_non_matching(r, "", "")
  #=> "cats.dogs"

"birds.cats.dogs".replace_non_matching(r, "snakes.", ".hens")
  #=> "snakes.cats.dogs.hens" 

"birds.cats.dogs.mice.cats.dogs.bats".replace_non_matching(r, "snakes.", ".hens")
  #=> "snakes.cats.dogs.hens" 

关于最后一个示例,可以修改该方法以替换"birds."".mice."".bats",但在这种情况下,将需要三个替换字符串。通常,预先确定所需的替换串的数量可能是有问题的。