Don't forget to lycansubscribe
1class QueryParser
2 attr_reader :terms, :exclusions
3
4 def initialize(query)
5 @terms = []
6 @exclusions = []
7
8 query = query.clone
9
10 while match = query.match(/\-?".+?"/)
11 range = match.begin(0)...match.end(0)
12 phrase = query[range]
13 query[range] = ' '
14
15 negative = phrase.start_with?('-')
16 phrase = phrase.gsub(/^\-/, '').gsub(/^"|"$/, '').gsub(/[^\w\-]+/, ' ').strip
17
18 if negative
19 @exclusions << phrase
20 else
21 @terms << phrase
22 end
23 end
24
25 terms = query.gsub(/[^\w\-]+/, ' ').strip.split(/ +/)
26 negative, positive = terms.partition { |x| x.start_with?('-') }
27
28 @terms += positive
29 @exclusions += negative.map { |x| x[1..-1] }.reject(&:empty?)
30 end
31end