Ricerca…


Gruppi, nominati e non.

Ruby estende la sintassi di gruppo standard (...) con un gruppo denominato, (?<name>...) . Ciò consente l'estrazione per nome invece di dover contare quanti gruppi hai.

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

L'indice della partita viene contato in base all'ordine delle parentesi sinistre (con l'intera espressione regolare il primo gruppo nell'indice 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"

= ~ operatore

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

Nota: l'ordine è significativo . Anche se 'haystack' =~ /hay/ è nella maggior parte dei casi equivalente, gli effetti collaterali possono essere diversi:

  • Le stringhe catturate dai gruppi di cattura con nome vengono assegnate alle variabili locali solo quando viene chiamato Regexp#=~ ( regexp =~ str );
  • Poiché l'operando corretto potrebbe essere un oggetto arbitrario, per regexp =~ str verrà chiamato Regexp#=~ o String#=~ .

Si noti che questo non restituisce un valore vero / falso, invece restituisce l'indice della corrispondenza se trovato, o zero se non trovato. Perché tutti gli interi in ruby ​​sono veri (compreso 0) e nil è falsi, questo funziona. Se si desidera un valore booleano, utilizzare #=== come mostrato in un altro esempio .

quantificatori

Quantificatori consente di specificare il conteggio delle stringhe ripetute.

  • Zero o uno:

    /a?/
    
  • Zero o molti:

    /a*/
    
  • Uno o molti:

    /a+/
    
  • Numero esatto:

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

Di default, i quantificatori sono avidi , il che significa che prendono più personaggi che possono mentre stanno ancora facendo una corrispondenza. Normalmente questo non è evidente:

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

Il site gruppo di cattura denominato sarà impostato su "Manutenzione e riparazione veicolo" come previsto. Ma se "Stack Exchange" è una parte facoltativa della stringa (perché potrebbe essere "Stack Overflow"), la soluzione ingenua non funzionerà come previsto:

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

Questa versione continuerà a combaciare, ma l'acquisizione nominata includerà 'Stack Exchange' dal momento che * mangia avidamente quei personaggi. La soluzione è aggiungere un altro punto interrogativo per rendere il * pigro:

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

Aggiunta ? a qualsiasi quantificatore lo renderà pigro.

Classi di caratteri

Descrive intervalli di simboli

È possibile enumerare i simboli in modo esplicito

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

O usare intervalli

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

È possibile combinare intervalli e singoli simboli

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

Il trattino principale ( - ) è trattato come personaggio

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

Le classi possono essere negative quando precedono i simboli con ^

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

Ci sono alcune scorciatoie per classi molto diffuse e personaggi speciali, oltre alle terminazioni di linea

^  # 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 sarà capito semplicemente come nuova linea

Per sfuggire a qualsiasi carattere riservato, come / o [] e altri usare il backslash (barra a sinistra)

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

Espressioni regolari nelle dichiarazioni del caso

È possibile verificare se una stringa corrisponde a diverse espressioni regolari utilizzando un'istruzione switch.

Esempio

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

Funziona perché le dichiarazioni del caso vengono verificate per l'uguaglianza usando l'operatore === , non l'operatore == . Quando una regex è sul lato sinistro di un confronto usando === , testerà una stringa per vedere se corrisponde.

Definire un Regexp

Un Regexp può essere creato in tre modi diversi in Ruby.

  • usando le barre: / /

  • utilizzando %r{}

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

incontro? - Risultato booleano

Restituisce true o false , che indica se la regexp è corretta o meno senza aggiornare $~ e altre variabili correlate. Se è presente il secondo parametro, specifica la posizione nella stringa per iniziare la ricerca.

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

Rubino 2.4+

Uso rapido comune

Le espressioni regolari vengono spesso utilizzate nei metodi come parametri per verificare se sono presenti altre stringhe o per cercare e / o sostituire stringhe.

Vedrai spesso quanto segue:

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

Quindi puoi semplicemente usarlo come controllo se una stringa contiene una sottostringa

puts "found" if string[/so/]

Più avanzato ma ancora breve e veloce: cerca un gruppo specifico usando il secondo parametro, 2 è il secondo in questo esempio perché la numerazione inizia da 1 e non da 0, un gruppo è ciò che è racchiuso tra parentesi.

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

Anche usato spesso: cerca e sostituisci con sub o gsub , \1 dà il primo gruppo trovato, \2 il secondo:

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

L'ultimo risultato è ricordato e può essere utilizzato nelle seguenti righe

$2 # gives long


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow