如何一次匹配多个正则表达式的行?

时间:2014-06-11 00:40:36

标签: ruby arrays regex text filter

我有一个包含标签的数组,通常是简单的英文单词,大约3-6个元素。我必须从文本文件中选择包含任何顺序的所有标记的行(大写或小写不计算,不区分大小写)。我怎样才能在Ruby中实现这一目标?我应该使用正则表达式还是任何不同的方法?

例如,我知道如何逻辑OR正则表达式模式/ tag1 | tag2 | tag3 / 是否可以以任何方式对它们进行逻辑运算? / tag1& tag2& tag3 /?

3 个答案:

答案 0 :(得分:5)

是。要对AND标记,请在字符串锚^开头后使用前瞻:

^(?=.*tag1)(?=.*tag2)(?=.*tag3).*

您可以通过循环遍历数组来以编程方式组装此正则表达式。

答案 1 :(得分:1)

这是你可以做到的一种方式。

<强>代码

def line_contains_tags(str, tags)
    str.scan(/(?:^|\s)(#{tags.join('|')})(?=\s|$)/)
       .flatten(1)
       .uniq.size == tags.size
end

<强>实施例

tags = %w{tag1 tag2 tag3}
line_contains_tags("tag1 tag2 tag3", tags) #=> true
line_contains_tags("tag2 tag1 tag3", tags) #=> true
line_contains_tags("tag1 tag3"     , tags) #=> false
line_contains_tags("tag1 tag1 tag3", tags) #=> false

<强>解释

正则表达式扫描字符串中tags的每个元素,直到找到匹配或结束没有匹配。匹配是tags的元素,前面是字符串的开头或空白字符,后跟一个由空格字符或字符串结尾组成的零长度(正向前瞻)字符串。 / p>

tags = %w{tag1 tag2 tag3}
  #=> ["tag1", "tag2", "tag3"]
regex = /(?:^|\s)(#{tags.join('|')})(?=\s|$)/
  #=> /(?:^|\s)(tag1|tag2|tag3)(?=\s|$)/

str = "tag1 tag2 tag3"
a = str.scan(regex)             #=> [["tag1"], ["tag2"], ["tag3"]]
b = a.flatten(1).uniq           #=> ["tag1", "tag2", "tag3"]
b.size == 3                     #=> true

对于最后一个例子,

str = "tag1 tag1 tag3"
a = str.scan(r).flatten(1).uniq #=> ["tag1", "tag3"]
a.size == 3                     #=> false

答案 2 :(得分:1)

非正则表达式方法是:

tags.all? {|tag| string.include? tag}

对于不区分大小写,假设string是一个下行线。和标签已经下降。

正则表达式更灵活;它们可以配置为匹配字边界等。