Ruby är ett av de mest populära språk som används på webben. Vi har startat en ny session här på Nettuts + som kommer att introducera dig till Ruby, liksom de stora ramarna och verktygen som följer med Ruby-utvecklingen. I den här lektionen ser vi på att använda regelbundet uttryck i Ruby.
Om du är bekant med reguljära uttryck kan du vara glad att veta att merparten av syntaxen för att skriva det verkliga reguljära uttrycket liknar vad du vet från PHP, JavaScript eller [ditt språk här].
Om du inte är bekant med reguljära uttryck, vill du kolla in våra Regex-handledning här på Nettuts + för att komma upp till fart.
Precis som allt annat i Ruby är reguljära uttryck vanliga föremål: de är instanser av Regexp
klass. Dock skapar du vanligtvis ett vanligt uttryck med den vanliga bokstavliga syntaxen:
/ myregex / / \ (\ d 3 \) \ d 3 - \ d 4 /
För att börja, är det enklaste sättet att använda en regexp att tillämpa den på en sträng och se om det finns en matchning. Både strängar och regexp föremål har a match
metod som gör det här:
"(123) 456-7890" .match / \ (\ d 3 \) \ d 3 - \ d 4 / / \ \ d 3 \) \ d 3 - \ d 4 /. Match "(123) 456-7890"
Båda dessa exempel matchar, och så ska vi få en MatchData
Exempel tillbaka (vi ska titta på MatchData
objekt snart). Om det inte finns någon matchning, match
kommer att återvända noll
. Eftersom a MatchData
objektet kommer att utvärderas till Sann
, du kan använda match
metod i villkorliga uttalanden (som ett if-statement) och bara ignorera att du får ett returvärde.
Det finns en annan metod som du kan använda för att matcha regexp med strängar: det är = ~
(likvärdig operatör). Kom ihåg att operatörer är metoder i Ruby. Tycka om match
, denna metod returnerar noll
utan match. Om det emellertid matchas kommer det att returnera den numeriska positionen för strängen där matchen startade. Också som match har både strängar och regexps = ~
.
"Ruby For Newbies: Regular Expressions" = ~ / Ny / # => 9
Regelbundna uttryck blir mer användbara när vi slänger ut några data. Detta görs vanligtvis med grupperingar: Inpakning av vissa delar av det reguljära uttrycket inom parentes. Låt oss säga att vi vill matcha ett förnamn, efternamn och yrke i en sträng, där strängen är formaterad så här:
str1 = "Joe Schmo, rörmokare" str2 = "Stephen Harper, premiärminister"
För att få de tre fälten skapar vi den här regexp:
re = / (\ w *) \ s (\ w *), \ s? ([\ w \ s] *) /
Detta matchar valfritt antal ordkaraktärer, viss blankutrymme, vilket antal ordtecken som helst, ett komma, en valfri blankutrymme och ett antal ordtecken eller mellanslag. Som du kan gissa, hänvisar delarna inklusive ordtecken till de namn eller yrke vi letar efter, så de är inslagna inom parentes.
Så, låt oss utföra detta:
match1 = str1.match re match2 = str2.match re
Nu, vår match1
och match2
variabler håller MatchData
objekt (eftersom båda våra matcher var framgångsrika). Så, låt oss se hur vi kan använda på dessa MatchData
objekt.
När vi går igenom det märker du att det finns några olika sätt att få samma data ut ur vårt MatchData
objekt. Vi börjar med den matchade strängen: Om du vill se vad den ursprungliga strängen som matchades med regexp använder du sträng
metod. Du kan också använda []
(square brackets) metod och passera parametern 0
:
match1.string # => "Joe Schmo, rörmokare" match1 [0] # (det här är detsamma som match1. [] 0) => "Joe Schmo, rörmokare"
Vad sägs om det vanliga uttrycket i sig? Du kan hitta det med regexp
metod.
match1.regex # => wsw, s [ws] (detta är IRB: s unika sätt att visa reguljära uttryck, det fungerar fortfarande normalt)
Nu, vad sägs om att få de matchade grupperna som var meningen med denna övning? För det första kan vi få dem med numrerade index på MatchData
objektet själv Naturligtvis är de i den ordning vi matchade dem i:
match1 [1] # => "Joe" match1 [2] # => "Schmo" match1 [3] # => "Rörmokare" match2 [1] # => "Stephen" match2 [2] # => "Harper" match2 [3] # => "premiärminister"
Det finns faktiskt ett annat sätt att få dessa fångar: det är med matrisegenskapen fångar
; Eftersom det här är en array, är den nollbaserad.
match1.captures [0] # => "Joe" match2.captures [2] # => "Prime Minister"
Tro det eller inte, det finns faktiskt ett tredje sätt att få dina fångar. När du kör match
eller = ~
, Ruby fyller i en rad globala variabler, en för varje fångad grupp i din regexp:
"Andrew Burgess". Match / (\ w *) \ s (\ w *) / # returnerar ett MatchData-objekt, men vi ignorerar det $ 1 # => "Andrew" $ 2 # => "Burgess"
Tillbaka till MatchData
objekt. Om du vill ta reda på strängindexet för en given infångning, skicka fångstnumret till Börja
funktionen (här vill du fånga numret som du skulle använda det med []
metod, inte via fångar
). Alternativt kan du använda slutet
för att se när den fångsten slutar.
m = "Nettuts + är det bästa" .match / (is) (mn) / m [1] # => "är" m.begin 1 # => 8 m [2] # => "slut" m.end 2 # => 14
Det finns också pre_match
och post_match
metoder, som är ganska snygga: det här visar vilken del av strängen som kom före respektive efter matchen.
# m ovanifrån m.pre_match # => "Webuts +" m.post_match # => "bästa"
Det handlar ganska mycket om grunderna för att arbeta med regelbundna uttryck i Ruby.
Eftersom regelbundna uttryck är så användbara när man hanterar strängar hittar du flera strängmetoder som utnyttjar dem. De mest användbara är förmodligen substitutionsmetoderna. Dessa inkluderar
sub
sub!
gsub
gsub!
Dessa är för substitution respektive global substitution. Skillnaden är det gsub
ersätter alla fall av vårt mönster, medan sub
ersätter endast första instansen i strängen.
Så här använder vi dem:
"någon sträng" .sub / string /, "message" # => "något meddelande" "mannen i parken" .gsub / the /, "a" # => "en man i en park"
Som du kanske vet är bangmetoderna (de som slutar med ett utropstecken!) Destruktiva metoder: dessa ändrar själva strängobjekten, istället för att återvända nu. Till exempel:
original = "Jag heter Andrew." new = original.sub / Mitt namn är /, "Hej, jag är" original # => Jag heter Andrew. "new # =>" Hej, jag är Andrew "original =" Vem är du? "original. sub! / Vem är /, "Och" original # => "Och du?"
Förutom dessa enkla exempel kan du göra mer komplexa saker, så här:
"1234567890" .ub / (\ d 3) (\ d 3) (\ d 4) /, '(\ 1) \ 2- \ 3' # => "(123) 456-7890 "
Vi får inte MatchData
objekt eller globala variabler med substitutionsmetoderna Vi kan dock använda backslash-numret? mönster i ersättningssträngen, om vi sätter i det i enkla citat. Om du vill manipulera den fångade strängen ytterligare kan du skicka ett block istället för den andra parametern:
"Vad går det?". Gsub (/ \ S * /) | s | s.downcase # => "Vad händer?"
Det finns många andra funktioner som använder reguljära uttryck; Om du är intresserad, bör du kolla in String # scan
och String # split
, till att börja.
Vi kommer att det är vanliga uttryck i Ruby för dig. Om du har några frågor, låt oss höra dem i kommentarerna.