解决方案 1
这样做:
r = patterns.select{|pattern| content =~ pattern}
由于字符串很大,最好在String 上实现这个方法,而不是在其他东西上,因为传递一个大参数似乎很慢。
class String
def filter_patterns patterns
patterns.select{|r| self =~ pattern}
end
end
并像这样使用它:
content.filter_patterns(patterns)
解决方案 2
限制每个正则表达式不包含命名/编号的捕获。
combined_regex = Regexp.new(patterns.map{|r| "(?=[.\n]*(#{r.source}))?"}.join)
content =~ combined_regex
如果patterns 中的正则表达式包含命名/编号捕获,则以下部分将出现问题。如果有办法知道每个正则表达式有多少潜在捕获,那么它将解决问题。
r = patterns.select.with_index{|pattern, i| Regexp.last_match[i]}
加法
给定:
dogs = {
'saluki' => 'Hounds',
'russian wolfhound' => 'Hounds',
'italian greyhound' => 'Hounds',
..
}
content = "Running in the fields at great speeds, the sleek saluki dog comes from..."
你可以这样做:
combined_regex =
Regexp.new(dogs.keys.map{|w| "(?=[.\n]*(#{w}))?"}.join, Regexp::IGNORECASE)
content =~ combined_regex
r = patterns.select.with_index{|pattern, i| Regexp.last_match[i]}
"This article talks about #{r.collect{|x| dogs[x]}.to_sentence}."
=> "This article talks about Hounds."
为避免像This article talks about Hounds, Hounds and Hounds. 这样的输出,您可能需要将uniq 放入其中。
"This article talks about #{r.uniq.collect{|x| dogs[x]}.to_sentence}."