Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

string.include?(other_string) is used to check if a string contains another string. Is there a nice way to check if a string contains at least one string 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 would return true, because string_1 contains the string 'animal'. If we remove 'animal' from arrays_of_strings_to_check_against, it would return false.

Note that the string 'dog' from arrays_of_strings_to_check_against should not match 'dogs' from string_1, because it has to be a complete match.

I'm using Rails 3.2.0 and Ruby 1.9.2

like image 275
ben Avatar asked May 31 '12 02:05

ben


People also ask

How do you check if a string contains a string from an array?

You can use the includes() method in JavaScript to check if an item exists in an array. You can also use it to check if a substring exists within a string. It returns true if the item is found in the array/string and false if the item doesn't exist.

How do you check if a string contains a certain substring?

The easiest and most effective way to see if a string contains a substring is by using if ... in statements, which return True if the substring is detected. Alternatively, by using the find() function, it's possible to get the index that a substring starts at, or -1 if Python can't find the substring.

How do I check if a string contains one character?

You can use string. indexOf('a') . If the char a is present in string : it returns the the index of the first occurrence of the character in the character sequence represented by this object, or -1 if the character does not occur.

How do you check if a string contains text from an array of substrings Python?

To check if a Python string contains the desired substring, you can use the "in" operator or the string. find() method. To get the first index of a substring in a string, you can use the string. index().


3 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/ }
like image 153
xdazz Avatar answered Nov 15 '22 06:11

xdazz


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 get nil there was no match; otherwise you'll get an integer (which you can treat just like true) that is the index of the offset where the match occurred.

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

any_match = !!(str =~ word_test)

The regular expression created by interpolation is:

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

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

Edit: The answer above no longer uses Regexp.union since that creates a case-sensitive regex, while the question requires case-insensitive.

Alternatively, we can force everything to lowercase before the test to gain case-insensitivity:

words = %w[baNanA Fruit ANIMAL dog]
word_test = /\b#{ Regexp.union(words.map(&:downcase)) }\b/
p str1.downcase =~ word_test,
  str2.downcase =~ word_test
like image 33
Phrogz Avatar answered Nov 15 '22 06:11

Phrogz


If array_of_strings_to_check_against contains only whole words, and not multi-word strings, you can & the two arrays together. If the result has length > 0, there was a match. Prior to .split(' '), however, you must remove non-word, non-space characters. Otherwise, in this case it would fail because animal. (with .) isn't 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
like image 36
Michael Berkowski Avatar answered Nov 15 '22 08:11

Michael Berkowski