Поиск…


Группы, названные и другие.

Ruby расширяет стандартный синтаксис группы (...) с именованной группой (?<name>...) . Это позволяет извлекать по имени вместо того, чтобы подсчитывать, сколько групп у вас есть.

name_reg = /h(i|ello), my name is (?<name>.*)/i #i means case insensitive

name_input = "Hi, my name is Zaphod Beeblebrox"

match_data = name_reg.match(name_input) #returns either a MatchData object or nil
match_data = name_input.match(name_reg) #works either way

if match_data.nil? #Always check for nil! Common error.
  puts "No match"
else
  match[0] #=> "Hi, my name is Zaphod Beeblebrox"
  match[1] #=> "i" #the first group, (i|ello)
  match[2] #=> "Zaphod Beeblebrox"
  #Because it was a named group, we can get it by name
  match[:name]  #=> "Zaphod Beeblebrox"
  match["name"] #=> "Zaphod Beeblebrox"
  puts "Hello #{match[:name]}!"
end

Индекс совпадения подсчитывается в соответствии с порядком левых скобок (при этом все регулярное выражение является первой группой с индексом 0)

reg = /(((a)b)c)(d)/
match = reg.match 'abcd'
match[0] #=> "abcd"
match[1] #=> "abc"
match[2] #=> "ab"
match[3] #=> "a"
match[4] #=> "d"

= ~ оператор

if /hay/ =~ 'haystack'
  puts "There is hay in the word haystack"
end

Примечание: порядок значителен . Хотя 'haystack' =~ /hay/ в большинстве случаев эквивалентен, побочные эффекты могут различаться:

  • Строки, взятые из названных групп захвата, присваиваются локальным переменным только при Regexp#=~ ( regexp =~ str );
  • Поскольку правильным операндом может быть произвольный объект, для regexp =~ str будет вызываться либо Regexp#=~ либо String#=~ .

Обратите внимание, что это не возвращает значение true / false, вместо этого возвращает либо индекс совпадения, если найден, либо nil, если не найден. Поскольку все целые числа в ruby ​​являются правдивыми (включая 0), а nil - ложными, это работает. Если вы хотите логическое значение, используйте #=== как показано в другом примере .

Кванторы

Квантификаторы позволяют указать количество повторяющихся строк.

  • Нулевой или один:

    /a?/
    
  • Нуль или много:

    /a*/
    
  • Один или многие:

    /a+/
    
  • Точное число:

    /a{2,4}/ # Two, three or four
    /a{2,}/  # Two or more
    /a{,4}/  # Less than four (including zero)
    

По умолчанию кванторы являются жадными , что означает, что они принимают как можно больше символов, пока они все еще делают совпадение. Обычно это не заметно:

/(?<site>.*) Stack Exchange/ =~ 'Motor Vehicle Maintenance & Repair Stack Exchange'

Именованный site группы захвата будет настроен на «Обслуживание и ремонт автомобилей», как и ожидалось. Но если «Stack Exchange» является необязательной частью строки (потому что вместо нее может быть «переполнение стека»), наивное решение не будет работать так, как ожидалось:

/(?<site>.*)( Stack Exchange)?/

Эта версия по-прежнему будет соответствовать, но именованный захват будет включать «Stack Exchange», поскольку * жадно ест эти символы. Решение состоит в том, чтобы добавить еще один знак вопроса, чтобы сделать * ленивым:

/(?<site>.*?)( Stack Exchange)?/

Добавление ? любому квантору будет лениться.

Классы символов

Описывает диапазоны символов

Вы можете явно перечислять символы

/[abc]/ # 'a' or 'b' or 'c'

Или используйте диапазоны

/[a-z]/ # from 'a' to 'z'

Можно комбинировать диапазоны и отдельные символы

/[a-cz]/ # 'a' or 'b' or 'c' or 'z'

Ведущая тире ( - ) рассматривается как charachter

/[-a-c]/ # '-' or 'a' or 'b' or 'c'

Классы могут быть отрицательными, если предыдущие символы с ^

/[^a-c]/ # Not 'a', 'b' or 'c'

Есть несколько ярлыков для широко распространенных классов и специальных символов, плюс окончания строк

^  # Start of line
$  # End of line
\A # Start of string
\Z # End of string, excluding any new line at the end of string
\z # End of string
.  # Any single character
\s # Any whitespace character
\S # Any non-whitespace character
\d # Any digit
\D # Any non-digit
\w # Any word character (letter, number, underscore)
\W # Any non-word character
\b # Any word boundary

\n будет пониматься просто как новая строка

Чтобы избежать любого зарезервированного charachter, например / или [] а другие используют обратную косую черту (левая косая черта)

\\ # => \
\[\] # => []

Регулярные выражения в случаях

Вы можете проверить, соответствует ли строка нескольким регулярным выражениям с помощью оператора switch.

пример

case "Ruby is #1!"
when /\APython/
    puts "Boooo."
when /\ARuby/
    puts "You are right."
else 
    puts "Sorry, I didn't understand that."
end

Это работает, потому что аргументы case проверяются на равенство, используя оператор === , а не оператор == . Когда регулярное выражение находится в левой части сравнения с использованием === , оно проверит строку, чтобы увидеть, совпадает ли она.

Определение регулярного выражения

Regexp можно создать тремя способами в Ruby.

  • с помощью косых черт: / /

  • используя %r{}

  • использование Regex.new

    #The following forms are equivalent
    regexp_slash = /hello/
    regexp_bracket = %r{hello}
    regexp_new = Regexp.new('hello')
    
    string_to_match = "hello world!"
    
    #All of these will return a truthy value
    string_to_match =~ regexp_slash    # => 0
    string_to_match =~ regexp_bracket  # => 0
    string_to_match =~ regexp_new      # => 0
    

матч? - Логический результат

Возвращает true или false , что указывает, соответствует ли регулярное выражение или нет, без обновления $~ и других связанных переменных. Если присутствует второй параметр, он указывает позицию в строке, чтобы начать поиск.

/R.../.match?("Ruby")    #=> true
/R.../.match?("Ruby", 1) #=> false
/P.../.match?("Ruby")    #=> false

Ruby 2.4+

Обычное быстрое использование

Регулярные выражения часто используются в методах в качестве параметров для проверки наличия других строк или поиска и / или замены строк.

Вы часто увидите следующее:

string = "My not so long string"
string[/so/] # gives so
string[/present/] # gives nil
string[/present/].nil? # gives true

Таким образом, вы можете просто использовать это как проверку, если строка содержит подстроку

puts "found" if string[/so/]

Более продвинутый, но все же короткий и быстрый: найдите определенную группу, используя второй параметр, 2 - второй в этом примере, потому что нумерация начинается с 1, а не 0, группа - это то, что заключено в круглые скобки.

string[/(n.t).+(l.ng)/, 2] # gives long

Также часто используется: поиск и замена sub или gsub , \1 дает первую найденную группу, \2 - вторую:

string.gsub(/(n.t).+(l.ng)/, '\1 very \2') # My not very long string

Последний результат запоминается и может использоваться по следующим строкам

$2 # gives long


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow