Is there a good way to check if a row contains at least one row from an array of strings?

string.include?(other_string) used to check if a string contains another string. Is there a good way to check if a row contains at least one row from an array of strings?

 string_1 = "a monkey is an animal. dogs are fun" arrays_of_strings_to_check_against = ['banana', 'fruit', 'animal', 'dog'] 

This will return true because string_1 contains the string 'animal' . If we remove 'animal' from arrays_of_strings_to_check_against , it will return false .

Note that the string 'dog' from arrays_of_strings_to_check_against does not have to match the 'dogs' from string_1 because it must be complete.

I am using Rails 3.2.0 and Ruby 1.9.2

+6
source share
6 answers
 arrays_of_strings_to_check_against.map{ |o| string_1 =~ /\b#{Regexp.escape(o)}\b/ }.any? 

Or even:

 arrays_of_strings_to_check_against.any?{ |o| string_1 =~ /\b#{Regexp.escape(o)}\b/ } 
+7
source

If array_of_strings_to_check_against contains only whole words and not verbose strings, you can & combine two arrays. If the result has a length> 0, there was a match. Before .split(' ') , however, you should remove characters without a word, not spaces. Otherwise, in this case, it will fail, because animal. (p . ) is not in your array.

 if (string_1.gsub(/[^\w\s]/).split(' ') & array_of_strings_to_check_against).length > 0 puts "Match!!" end 

Update after comments: case insensitive version

 if (string_1.downcase.gsub(/[^\w\s]/).split(' ') & array_of_strings_to_check_against).length > 0 puts "Match!!" end 
+4
source
 str1 = "a monkey is an animal. dogs are fun" str2 = "a monkey is a primate. dogs are fun" words = %w[banana fruit animal dog] word_test = /\b(?:#{ words.map{|w| Regexp.escape(w) }.join("|") })\b/i p str1 =~ word_test, #=> 15 str2 =~ word_test #=> nil 

If you received nil , there was no match; otherwise, you get an integer (which can be treated exactly like true ), which is the offset index where the match occurred.

If you absolutely must have true or false , you can do:

 any_match = !!(str =~ word_test) 

A regular expression created by interpolation:

 /\b(?:banana|fruit|animal|dog)\b/i 

... where \b matches the "word boundary", thereby preventing dog from matching in dogs .

Change The above answer no longer uses Regexp.union , as this creates a case-sensitive regular expression, while the question requires case-insensitive.

Alternatively, we can force everyone to execute lowercase letters before the test to get case insensitive:

 words = %w[baNanA Fruit ANIMAL dog] word_test = /\b#{ Regexp.union(words.map(&:downcase)) }\b/ p str1.downcase =~ word_test, str2.downcase =~ word_test 
+3
source

Regexp.union is your friend in this case. Consider:

 # the words we're looking for... target_words = %w[ore sit ad sint est lore] search_text = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.' # define a search ignoring case that looks for partial words... partial_words_regex = /#{ Regexp.union(target_words).source }/i partial_words_regex.to_s # => "(?i-mx:ore|sit|ad|sint|est|lore)" # define a search ignoring case that looks for whole words... whole_words_regex = /\b(?:#{ Regexp.union(target_words).source })\b/i whole_words_regex.to_s # => "(?i-mx:\\b(?:ore|sit|ad|sint||lore)\\b)" # find the first hit... search_text[whole_words_regex] # => "sit" # find all partial word hits... search_text.scan(partial_words_regex) # => ["Lore", "sit", "ad", "ore", "lore", "ad", "lore", "sint", "est"] # find all whole word hits... search_text.scan(whole_words_regex) # => ["sit", "ad", "sint", "est"] 

Putting all this in context:

 string_1 = "a monkey is an animal. dogs are fun" arrays_of_strings_to_check_against = ['banana', 'fruit', 'animal', 'dog'] string_1[Regexp.union(arrays_of_strings_to_check_against)] # => "animal" string_1.scan(Regexp.union(arrays_of_strings_to_check_against)) # => ["animal", "dog"] 
+2
source
 def check_string arrays_of_string_to_check_against.each do |item| is_include = string_1.include?(item) end end 
0
source
 (string_1.scan(/\w+/) & arrays_of_strings_to_check_against).size > 0 
0
source

Source: https://habr.com/ru/post/917066/


All Articles