I have a string variable with content:
varMessage =
"hi/thsid/sdfhsjdf/dfjsd/sdjfsdn\n"
"/my/name/is/balaji.so\n"
"call::myFunction(int const&)\n"
"void::secondFunction(char const&)\n"
.
.
.
"this/is/last/line/liobrary.so"
In the string I have to find a sub-string:
"hi/thsid/sdfhsjdf/dfjsd/sdjfsdn\n"
"/my/name/is/balaji.so\n"
"call::myFunction(int const&)\n"
How can I find it? I need to determine whether the sub-string is present or not.
You can use the include?
method:
my_string = "abcdefg"
if my_string.include? "cde"
puts "String includes 'cde'"
end
If case is irrelevant, then a case-insensitive regular expression is a good solution:
'aBcDe' =~ /bcd/i # evaluates as true
This will also work for multi-line strings.
See Ruby's Regexp class for more information.
Regexp.escape
on the string. For most use cases, some_str.include? substr.downcase()
should work faster and be more readable.
'aBcDe'.downcase.include?('bcd')
. Regex have their purpose but don't use them when the built-in methods are faster. Benchmarking with the actual data being tested can reveal much.
/bcd/i.match?('aBcDe')
You can also do this...
my_string = "Hello world"
if my_string["Hello"]
puts 'It has "Hello"'
else
puts 'No "Hello" found'
end
# => 'It has "Hello"'
This example uses Ruby's String #[]
method.
#include?
is still a little faster.
#include?
doesn't work when you are working with sentences with spaces inside because #include
splits the sentence in words and then uses the words as separate array values. This works perfectly for sentences. +1
[]
method for more information.
include?
does not split the string. It simply checks if a string is or isn't within an other string. 'Hello World! How are you?'.include?('e y') #=> true
This answer does the same thing. 'Hello World! How are you?'['e y'] #=> "e y"
(which is truthy), nil
is returned if there is no match (which is falsy).
Expanding on Clint Pachl's answer:
Regex matching in Ruby returns nil
when the expression doesn't match. When it does, it returns the index of the character where the match happens. For example:
"foobar" =~ /bar/ # returns 3
"foobar" =~ /foo/ # returns 0
"foobar" =~ /zzz/ # returns nil
It's important to note that in Ruby only nil
and the boolean expression false
evaluate to false. Everything else, including an empty Array, empty Hash, or the Integer 0, evaluates to true.
That's why the /foo/
example above works, and why.
if "string" =~ /regex/
works as expected, only entering the 'true' part of the if
block if a match occurred.
if( ("foobar" =~ /foo/) == nil ) puts 'Not Found' else puts 'Found' end
It should work.
A more succinct idiom than the accepted answer above that's available in Rails (from 3.1.0 and above) is .in?
:
my_string = "abcdefg"
if "cde".in? my_string
puts "'cde' is in the String."
puts "i.e. String includes 'cde'"
end
I also think it's more readable.
See the in?
documentation for more information.
Note again that it's only available in Rails, and not pure Ruby.
in?
.
"cde".in? my_string
in pure Ruby yields NoMethodError
. But with require 'active_support/core_ext/object/inclusion'
it works, which can be loaded either from Rails itself or from the cut-down Active Support Core Extensions.
Ternary way
my_string.include?('ahr') ? (puts 'String includes ahr') : (puts 'String does not include ahr')
OR
puts (my_string.include?('ahr') ? 'String includes ahr' : 'String not includes ahr')
You can use the String Element Reference method which is []
Inside the []
can either be a literal substring, an index, or a regex:
> s='abcdefg'
=> "abcdefg"
> s['a']
=> "a"
> s['z']
=> nil
Since nil
is functionally the same as false
and any substring returned from []
is true
you can use the logic as if you use the method .include?
:
0> if s[sub_s]
1> puts "\"#{s}\" has \"#{sub_s}\""
1> else
1* puts "\"#{s}\" does not have \"#{sub_s}\""
1> end
"abcdefg" has "abc"
0> if s[sub_s]
1> puts "\"#{s}\" has \"#{sub_s}\""
1> else
1* puts "\"#{s}\" does not have \"#{sub_s}\""
1> end
"abcdefg" does not have "xyz"
Just make sure you don't confuse an index with a sub string:
> '123456790'[8] # integer is eighth element, or '0'
=> "0" # would test as 'true' in Ruby
> '123456790'['8']
=> nil # correct
You can also use a regex:
> s[/A/i]
=> "a"
> s[/A/]
=> nil
How to check whether a string contains a substring in Ruby?
When you say 'check', I assume you want a boolean returned in which case you may use String#match?
. match?
accepts strings or regexes as its first parameter, if it's the former then it's automatically converted to a regex. So your use case would be:
str = 'string'
str.match? 'strings' #=> false
str.match? 'string' #=> true
str.match? 'strin' #=> true
str.match? 'trin' #=> true
str.match? 'tri' #=> true
String#match?
has the added benefit of an optional second argument which specifies an index from which to search the string. By default this is set to 0
.
str.match? 'tri',0 #=> true
str.match? 'tri',1 #=> true
str.match? 'tri',2 #=> false
user_input = gets.chomp
user_input.downcase!
if user_input.include?('substring')
# Do something
end
This will help you check if the string contains substring or not
puts "Enter a string"
user_input = gets.chomp # Ex: Tommy
user_input.downcase! # tommy
if user_input.include?('s')
puts "Found"
else
puts "Not found"
end
In case you can not use one of the libs mentioned above, one could achieve the same with simple text search (this is ignoring cases because of downcase
):
ADD_BUTTON_TEXTS = ["add to cart", "add to basket"].freeze
target_text = "AdD tO cArT"
ADD_BUTTON_TEXTS.each do |text|
puts "Text was found" if target_text.downcase.include?(text)
end
Success story sharing
include?
is case sensetive. So ifmy_string
in the example above would be something like"abcDefg"
(with an uppercaseD
),include?("cde")
would returnfalse
. You may want to do adowncase()
before callinginclude?()
.to_s
will hide the problem and increase the distance between the source and the detection of the problem, making it harder to debug.test&.include?("test")