2009-06-16 20 views
155

Questo è quello che ho adesso - che sembra troppo prolisso per il lavoro che sta facendo.Qual è il modo canonico per tagliare una stringa in Ruby senza creare una nuova stringa?

@title  = tokens[Title].strip! || tokens[Title] if !tokens[Title].nil? 

Assumere token è una matrice ottenuta dividendo una linea CSV. ora le funzioni come striscia! chomp! et. tutto nil di ritorno, se la stringa non è stato modificato

"abc".strip! # => nil 
" abc ".strip! # => "abc" 

Qual è il modo di Ruby di dire ritagliarlo se contiene leader in più o spazi finali senza creare copie?

Gets più brutto se voglio fare tokens[Title].chomp!.strip!

+3

Se hai intenzione di leggere ripetutamente le cose da token, potrebbe avere più senso pre-elaborarli. I.e. "tokens.each {| t | tstst!}". quindi puoi semplicemente "@title = token [Title] || ''" –

risposta

227

Credo che quello che vuoi è:

@title = tokens[Title] 
@title.strip! 

Il metodo #strip! tornerà nil se non striscia nulla, e la variabile stessa se è stato spogliato.

Secondo gli standard Ruby, un metodo con suffisso con un punto esclamativo cambia la variabile in posizione.

Spero che questo aiuti.

Aggiornamento: Questo è uscita dal irb per dimostrare:

>> @title = "abc" 
=> "abc" 
>> @title.strip! 
=> nil 
>> @title 
=> "abc" 
>> @title = " abc " 
=> " abc " 
>> @title.strip! 
=> "abc" 
>> @title 
=> "abc" 
+0

Hmm .. penso comunque @title = token [Title] .strip! sembra più pulito - è un peccato che restituisca zero invece della stringa non modificata. A meno che qualcuno non pubblichi un ans migliore .. stai ricevendo il bit accettato. – Gishu

+5

Bene, @title = token [Titolo] .strip farà il trucco ma invece avresti una copia, che va bene se si mantiene invariata la variabile [Title] dei token. – Igor

+0

Se vuoi che un metodo restituisca la stringa non modificata, puoi facilmente creare la tua: def strip_returning_self() strip! || auto fine – Chuck

2

Credo che il vostro esempio è un approccio ragionevole, anche se si potrebbe semplificare un po 'come:

@title = tokens[Title].strip! || tokens[Title] if tokens[Title] 

alternativa si potrebbe metterlo su due righe:

@title = tokens[Title] || '' 
@title.strip! 
8

Non c'è bisogno sia di strip che di chomp perché strip rimuoverà anche i ritorni a capo a capo - a meno che tu non abbia cambiato il separatore di record predefinito e questo è ciò che stai masticando.

risposta di Olly ha già il modo canonico di fare questo in Ruby, ma se vi trovate a fare questo molto si può sempre definire un metodo per esso:

def strip_or_self!(str) 
    str.strip! || str 
end 

Dare:

@title = strip_or_self!(tokens[Title]) if tokens[Title] 

Ricorda inoltre che l'istruzione if impedirà l'assegnazione di @title se il token è nullo, il che comporterà il mantenimento del valore precedente.Se si desidera o non si mente @title essere sempre assegnato è possibile spostare il controllo nel metodo e ridurre ulteriormente la duplicazione:

def strip_or_self!(str) 
    str.strip! || str if str 
end 

In alternativa, se vi sentite avventurosi è possibile definire un metodo su stringa stessa :

class String 
    def strip_or_self! 
    strip! || self 
    end 
end 

Dando uno dei:

@title = tokens[Title].strip_or_self! if tokens[Title] 

@title = tokens[Title] && tokens[Title].strip_or_self! 
+0

Anche se non tecnicamente la risposta. Grazie .. non lo sapevo .. – Gishu

44

Btw, ora rubino già supporta solo striscia senza "!".

Confronta:

p "abc".strip! == " abc ".strip! # false, because "abc".strip! will return nil 
p "abc".strip == " abc ".strip # true 

Inoltre è impossibile strip senza duplicati. Vedi fonti in string.c:

static VALUE 
rb_str_strip(VALUE str) 
{ 
    str = rb_str_dup(str); 
    rb_str_strip_bang(str); 
    return str; 
} 

rubino 1.9.3p0 (2011-10-30) [i386-mingw32]

Update 1: Per come la vedo ora - è stato creato nel 1999 anno (cfr rev #372 in SVN):

Update2: strip! non creerà i duplicati - versioni sia in 1.9.x, 2.x e del tronco.

+0

"è impossibile spogliarsi senza duplicati" - ovviamente è possibile, questo è ciò che 'strip! 'È per. –

+0

@KarolyHorvath non vedi il codice sorgente, scritto in C? Pls leggere attentamente, ciò che ho scritto qui per quanto riguarda i duplicati. – gaRex

+0

Certo che lo vedo. Ma questo è il codice sorgente di 'strip'. Ho frainteso qualcosa? In quale altro modo potrei interpretare "impossibile da spogliare senza duplicare"? –

2

Il mio modo:

> (@title = " abc ").strip! 
=> "abc" 
> @title 
=> "abc" 
0
@title = tokens[Title].strip! || tokens[Title] 

'del tutto possibile non sto capire l'argomento, ma non sarebbe questo fare quello che ti serve?

" success ".strip! || "rescue" #=> "success" 
"failure".strip! || "rescue" #=> "rescue" 
1

Se si hanno o rubino 1.9 o ActiveSupport, si può fare semplicemente

@title = tokens[Title].try :tap, &:strip! 

Questo è davvero cool, in quanto sfrutta la :try e il metodo :tap, che sono le più potenti costrutti funzionali rubino, secondo me.

Una forma ancora più carini, le funzioni di passaggio come simboli del tutto:

@title = tokens[Title].send :try, :tap, &:strip! 
5

Se si utilizza Ruby on Rails c'è una squish

> @title = " abc " 
=> " abc " 

> @title.squish 
=> "abc" 
> @title 
=> " abc " 

> @title.squish! 
=> "abc" 
> @title 
=> "abc" 

Se si utilizza solo Rubino si desidera utilizzare la striscia

Qui sta il gotcha .. nel tuo caso si desidera utilizzare s viaggio senza il botto!

mentre striscia! certamente non restituisce nulla se non c'è azione, ma aggiorna la variabile in modo tale che rimuova! non può essere usato in linea. Se vuoi usare strip inline puoi usare la versione senza il botto!

striscia! utilizzando approccio multi linea

> tokens["Title"] = " abc " 
=> " abc " 
> tokens["Title"].strip! 
=> "abc" 
> @title = tokens["Title"] 
=> "abc" 

striscia unico approccio line ... LA RISPOSTA

> tokens["Title"] = " abc " 
=> " abc " 
> @title = tokens["Title"].strip if tokens["Title"].present? 
=> "abc" 
2

Se si desidera utilizzare un altro metodo dopo aver bisogno di qualcosa di simile:

(str.strip || str).split(',') 

In questo modo è possibile rimuovere e continuare a fare qualcosa dopo :)

Problemi correlati