ChatGPT解决这个技术问题 Extra ChatGPT

How to check whether a string contains a substring in Ruby

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.

See stackoverflow.com/a/3878656/128421 for a breakdown of various ways to do this.

D
Dave Powers

You can use the include? method:

my_string = "abcdefg"
if my_string.include? "cde"
   puts "String includes 'cde'"
end

Remember that include? is case sensetive. So if my_string in the example above would be something like "abcDefg" (with an uppercase D), include?("cde") would return false. You may want to do a downcase() before calling include?().
Include on it's own is not ideal as it can throw a NoMethodError if nil test = nil test.include?("test") NoMethodError: undefined method `include?' for nil:NilClass should always convert the value being included to the expected value:- test.to_s.include?("test")
@Gary's advice holds if your goal is to minimize exceptions raised in this part of the code. That is not always the best goal. Generally if you expect a string at this point in the code and a value is nil instead, that implies something unexpected has occurred and an exception being raised is appropriate. If the existence of a nil here is unexpected, using to_s will hide the problem and increase the distance between the source and the detection of the problem, making it harder to debug.
Alternatively, avoid sending methods to nil with a safe navigation operator test&.include?("test")
t
the Tin Man

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.


If you are matching against user input and using this technique, remember to use Regexp.escape on the string. For most use cases, some_str.include? substr.downcase() should work faster and be more readable.
Using a regular expression this way isn't necessarily going to be faster than using '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.
This does NOT evaluate as true. It evaluates to 1 which is not true.
!!('aBcDe' =~ /bcd/i) will evaluate to true or false. Use the !! idiom
alternatively, use match? to return a boolean: /bcd/i.match?('aBcDe')
O
Oto Brglez

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.


This is a neat trick I've not seen before. But #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
See Ruby's String [] method for more information.
@luissimo 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).
t
the Tin Man

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.
t
the Tin Man

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.


This relies on rails, the OP asked for a ruby solution
That's right, although since a significant proportion of Ruby developers are using Rails, I thought this might be a preferred solution for some due to its clarity and brevity.
See stackoverflow.com/a/4239625/128421. It's in Rails, but is easily accessed from regular Ruby using Rails' Active Support Core Extensions which allow easy cherry-picking of small groups of methods such as only in?.
Correct @theTinMan. "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.
B
BSMP

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')

d
dawg

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

S
Sagar Pandya

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

P
Prabhakar Undurthi
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

d
d1jhoni1b

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