Решение 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}."