Ruby: Какой правильный синтаксис для логического метода regex?

Каков правильный синтаксис метода, который проверяет строку для шаблона и возвращает true или false, если регулярное выражение соответствует?

Основная идея:

def has_regex?(string)
    pattern = /something/i
    return string =~ pattern
end

Случай использования:

if has_regex?("something")
    # woohoo
else
    # nothing found: panic!
end

Ответы

Ответ 1

Если вы хотите поместить шаблон в метод, вы можете просто сделать

def has_my_pattern(st)
    st =~ /pattern/
end

Или, может быть, лучше поместить шаблон в переменную класса?

Ответ 2

В вопросе, который вы сказали:

... метод, который проверяет строку для шаблона и возвращает true или false, если регулярное выражение соответствует

Как johannes указал String=~ возвращает nil, если шаблон не совпал и позиция в строке, где совпадающее слово смотрело иначе. Далее он заявляет в Ruby все, кроме nil и false ведет себя как true. Все это правильно.

Однако они не точно true или false. Поэтому последним шагом является принудительное значение значения Boolean. Это достигается путем обертывания результата в double bangs, возвращает a true.

def has_regex?(string)
    !!(string =~ /something/i)
end

Ответ 3

Ваш код выглядит отлично, но вы можете записать его еще меньше.

Возвращаемое значение String#=~ ведет себя следующим образом:

  • nil, если шаблон не соответствует
  • позиция в строке, где началось совпадающее слово

В Ruby все, кроме nil и false, ведет себя как true в условном выражении, поэтому вы можете просто написать

if string=~ pattern
  # do something
else
  # panic
end

Ответ 4

Чтобы вернуть true/false, установите положение шаблона и строки и используйте случайное равенство ===

def has_regex?(string)
    pattern = /something/i
    return pattern === string
end

Мне абсолютно нужно было вернуть истинное булевское значение и выкопать его. Он действительно документирован в классе regexp http://www.ruby-doc.org/core-2.1.3/Regexp.html#method-i-3D-3D-3D

Ответ 5

Добавление этого в класс String делает его довольно простым в использовании:

   class String
      def match?(regex)
          !!self.match(regex)
      end
   end

Я добавил его в Rails initializer (RAILS_ROOT/config/initializers), и вы можете вызывать прямо из строки:

"Something special!".match?(/something/i) #=> true 
"Somethin' special!".match?(/something/i) #=> false 

Ответ 6

Если вы используете Ruby 2.4 или новее, существуют методы String#match?(regex) и Regexp#match?(string), которые возвращают логические значения без преобразования shenanigans (там, где это необходимо, обычно нет), и имеют улучшенную производительность для загрузки.

https://ruby-doc.org/core-2.4.0/Regexp.html#method-i-match-3F

https://blog.cognitohq.com/new-features-in-ruby-2-4/

Ответ 7

Для любой будущей ссылки двойные челки не одобряются из bbatsov ruby ​​style guide. Вместо того, чтобы использовать двойной взлом, просто проверьте, не имеет ли значение nil. Если значение не равно nil, оно существует.

Вместо этого:

def has_regex?(string)
  !!(string =~ /something/i)
end

Вы всегда можете сделать это:

def has_regex?(string)
  !(string =~ /something/i).nil?
end

Ответ 8

Как я хотел, чтобы это работало в целом, а не только для какого-либо конкретного проекта, я вообще не хочу изменять среду.

Мне удалось заставить его работать, просто используя возвращаемое значение из обычного метода match в качестве условного. Протестировано как положительный, так и отрицательный случай в этой строке примера:

irb(main):014:0> if "123".match(/.2./); puts "worked"; end
worked
=> nil
irb(main):015:0> if "123".match(/.3./); puts "worked"; end
=> nil

Ответ 9

Для Ruby >= 2.4 или Rails вы можете сделать:

 regexp.match?(string)