Buscar..


Grupos, nombrados y otros.

Ruby extiende la sintaxis estándar del grupo (...) con un grupo nombrado, (?<name>...) . Esto permite la extracción por nombre en lugar de tener que contar cuántos grupos tiene.

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

El índice de la coincidencia se cuenta según el orden de los paréntesis izquierdos (con la expresión regular completa como el primer grupo en el índice 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"

= operador ~

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

Nota: El orden es significativo . Aunque 'haystack' =~ /hay/ es en la mayoría de los casos un equivalente, los efectos secundarios pueden diferir:

  • Las cadenas capturadas de los grupos de captura nombrados se asignan a las variables locales solo cuando se llama a Regexp#=~ ( regexp =~ str );
  • Como el operando correcto podría ser un objeto arbitrario, para regexp =~ str se llamará Regexp#=~ o String#=~ .

Tenga en cuenta que esto no devuelve un valor verdadero / falso, en su lugar devuelve el índice de la coincidencia si se encuentra, o nil si no se encuentra. Debido a que todos los enteros en ruby ​​son veraces (incluido 0) y nil es falsy, esto funciona. Si desea un valor booleano, use #=== como se muestra en otro ejemplo .

Cuantificadores

Los cuantificadores permiten especificar el recuento de cadenas repetidas.

  • Cero o uno:

    /a?/
    
  • Cero o muchos:

    /a*/
    
  • Uno o muchos:

    /a+/
    
  • Numero exacto:

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

Por defecto, los cuantificadores son codiciosos , lo que significa que toman la mayor cantidad de caracteres que pueden mientras hacen una coincidencia. Normalmente esto no se nota:

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

El site grupo de captura nombrado se configurará en "Mantenimiento y reparación de vehículos de motor" como se esperaba. Pero si 'Stack Exchange' es una parte opcional de la cadena (porque podría ser 'Stack Overflow' en su lugar), la solución ingenua no funcionará como se esperaba:

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

Esta versión aún coincidirá, pero la captura nombrada incluirá 'Intercambio de pila' ya que * come con avidez esos personajes. La solución es agregar otro signo de interrogación para que el * perezoso:

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

? Anexando ? a cualquier cuantificador lo hará perezoso.

Clases de personajes

Describe rangos de símbolos.

Puedes enumerar símbolos explícitamente

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

O utilizar rangos

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

Es posible combinar rangos y símbolos únicos.

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

El guión inicial ( - ) se trata como un personaje.

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

Las clases pueden ser negativas cuando los símbolos anteriores con ^

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

Hay algunos accesos directos para clases generalizadas y caracteres especiales, además de finales de línea.

^  # 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 será entendido simplemente como nueva línea

Para escapar de cualquier personaje reservado, como / o [] y otros, utilice la barra invertida (barra izquierda)

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

Expresiones regulares en declaraciones de casos

Puede probar si una cadena coincide con varias expresiones regulares usando una instrucción switch.

Ejemplo

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

Esto funciona porque se comprueba la igualdad de las declaraciones de casos utilizando el operador === , no el operador == . Cuando una expresión regular está en el lado izquierdo de una comparación utilizando === , probará una cadena para ver si coincide.

Definiendo un Regexp

Un Regexp se puede crear de tres maneras diferentes en Ruby.

  • utilizando barras: / /

  • utilizando %r{}

  • usando 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
    

¿partido? - Resultado booleano

Devuelve true o false , que indica si la expresión regular coincide o no sin actualizar $~ y otras variables relacionadas. Si el segundo parámetro está presente, especifica la posición en la cadena para comenzar la búsqueda.

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

Ruby 2.4+

Uso rápido común

Las expresiones regulares a menudo se usan en métodos como parámetros para verificar si hay otras cadenas presentes o para buscar y / o reemplazar cadenas.

A menudo verá lo siguiente:

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

Así que simplemente puedes usar esto como una verificación si una cadena contiene una subcadena

puts "found" if string[/so/]

Más avanzado pero aún breve y rápido: busque un grupo específico utilizando el segundo parámetro, 2 es el segundo en este ejemplo porque la numeración comienza en 1 y no en 0, un grupo es lo que está entre paréntesis.

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

También se usa a menudo: buscar y reemplazar con sub o gsub , \1 da el primer grupo encontrado, \2 el segundo:

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

El último resultado se recuerda y se puede utilizar en las siguientes líneas

$2 # gives long


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow