Sök…


Grupper, namngivna och annars.

Ruby utökar standardgruppssyntaxen (...) med en namngiven grupp, (?<name>...) . Detta möjliggör extraktion med namn istället för att behöva räkna hur många grupper du har.

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

Matchens index räknas baserat på ordningen för de vänstra parenteserna (med hela regexet som den första gruppen i index 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"

= ~ operatör

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

Obs! Beställningen är viktig . Även om 'haystack' =~ /hay/ är i de flesta fall en ekvivalent, kan biverkningar skilja sig åt:

  • Strängar fångade från namngivna fångstgrupper tilldelas endast lokala variabler när Regexp#=~ kallas ( regexp =~ str );
  • Eftersom rätt operand kan vara är ett godtyckligt objekt, för regexp =~ str kommer det att kallas antingen Regexp#=~ eller String#=~ .

Observera att detta inte returnerar ett sant / falskt värde, utan istället returnerar antingen matchens index om det hittas, eller noll om det inte hittas. Eftersom alla heltal i rubin är sanningsenliga (inklusive 0) och noll är falskt fungerar det. Om du vill ha ett booleskt värde, använd #=== som visas i ett annat exempel .

Kvantifierare

Kvantifierare tillåter att ange antal av upprepade strängar.

  • Noll eller en:

    /a?/
    
  • Noll eller många:

    /a*/
    
  • En eller många:

    /a+/
    
  • Exakt antal:

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

Som standard är kvantifierare giriga , vilket innebär att de tar så många tecken som de kan medan de fortfarande gör en matchning. Normalt märks detta inte:

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

Den namngivna capture gruppen site kommer att sättas till '' Motor Vehicle Underhåll och reparation' som förväntat. Men om 'Stack Exchange' är en valfri del av strängen (eftersom det istället kan vara 'Stack Overflow') fungerar den naiva lösningen inte som förväntat:

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

Den här versionen kommer fortfarande att matcha, men den namngivna inspelningen kommer att inkludera "Stack Exchange" eftersom * girigt äter dessa tecken. Lösningen är att lägga till ytterligare ett frågetecken för att göra * lata:

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

Bifogar du ? till någon kvantifierare kommer att göra det lat.

Karaktär klasser

Beskriver symboler

Du kan räkna upp symboler uttryckligen

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

Eller använd intervall

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

Det är möjligt att kombinera intervall och enstaka symboler

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

Ledande streck ( - ) behandlas som charachter

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

Klasserna kan vara negativa när de föregående symboler med ^

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

Det finns några genvägar för utbredda klasser och speciella charachter plus linjeavslut

^  # 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 förstås helt enkelt som en ny linje

För att undkomma alla reserverade charachter, till exempel / eller [] och andra, använder backslash (vänster snedstreck)

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

Regelbundna uttryck i ärendedeklarationer

Du kan testa om en sträng matchar flera reguljära uttryck med ett switch-uttalande.

Exempel

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

Detta fungerar på grund av att === kontrolleras för jämlikhet med operatören === , inte operatören == . När en regex finns på vänster sida av en jämförelse med === testar den en sträng för att se om den matchar.

Definiera en Regexp

En Regexp kan skapas på tre olika sätt i Ruby.

  • med snedstreck: / /

  • använder %r{}

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

match? - Booleskt resultat

Returnerar true eller false , vilket indikerar om regexp matchas eller inte utan att uppdatera $~ och andra relaterade variabler. Om den andra parametern finns, anger den positionen i strängen för att börja söka.

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

Ruby 2.4+

Vanlig snabb användning

Vanliga uttryck används ofta i metoder som parametrar för att kontrollera om andra strängar finns eller för att söka och / eller ersätta strängar.

Du ser ofta följande:

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

Så du kan helt enkelt använda detta som en kontroll om en sträng innehåller en substring

puts "found" if string[/so/]

Mer avancerad men fortfarande kort och snabb: sök efter en specifik grupp med hjälp av den andra parametern, 2 är den andra i det här exemplet eftersom numrering börjar på 1 och inte 0, en grupp är vad som är inneslutet inom parentes.

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

Ofta används: sök och ersätt med sub eller gsub , \1 ger den första hittade gruppen, \2 den andra:

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

Det sista resultatet kommer ihåg och kan användas på följande rader

$2 # gives long


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow