简体   繁体   中英

String includes another string or regex (Ruby)

I need to check if given String includes a string or regex. If it does, it should return true, otherwise - false. How can I do it?

I have:

def method(string)
  if @text.match(/#{string}/)
    true
  else
    false
  end
end

But I'm not sure if it's a proper way.

Consider this:

@text = 'foobar'

def method1(string)
  if @text.match(/#{string}/)
    true
  else
    false
  end
end

That can be reduced to:

def method2(string_or_regex)
  if @text[string_or_regex]
    true
  else
    false
  end
end

String's [] method allows us to pass in a string or a pattern. If it's a string, the method uses it for a fixed-string/in-string search. If a pattern is passed in it returns the matching text.

However, Ruby is more friendly than this. We don't have to tell it to return a true or false value conditionally. In Ruby, a nil or false value is treated as false, and anything else is "truethy". We can convert a value to true/false using !! , which is double boolean "not":

true # => true
'foo' # => "foo"
false # => false
nil # => nil

!true # => false
!'foo' # => false
!false # => true
!nil # => true

!!true # => true
!!'foo' # => true
!!false # => false
!!nil # => false

Knowing that, and that String's [] returns a nil if not found, or the matching text if found:

'foo'['foo'] # => "foo"
'foo'['bar'] # => nil

we can reduce the original method to:

def method3(string_or_regex)
  !!@text[string_or_regex]
end

Here's what happens testing each of the methods above:

method1('foo') # => true
method1('baz') # => false

method2('foo') # => true
method2(/foo/) # => true
method2('baz') # => false
method2(/baz/) # => false

method3('foo') # => true
method3(/foo/) # => true
method3('baz') # => false
method3(/baz/) # => false

You have to be careful interpolating a regular expression object into another regular expression:

string = /foo/
/#{string/ # => /(?-mix:foo)/

The (?-mix: are the pattern flags being inserted inside another pattern, which can open your pattern to all sorts of weird behaviors and create extremely hard to find bugs. Instead, I strongly recommend using the source method if you're going to do that, which results in the original pattern being inserted:

/#{string.source}/ # => /foo/

单行代码:

!@text.match(/#{string}/).nil?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM