2011-01-11 24 views
26

Non sono sicuro di come si faccia, dato che sono abbastanza nuovo per le espressioni regolari, e non riesco a trovare il metodo corretto per farlo ma dico che ho il seguente come stringa (tutte le schede, e ritorni a capo inclusi)Ruby riduce tutti gli spazi bianchi a spazi singoli

1/2 cup 




      onion   
      (chopped) 

Come faccio a rimuovere tutti gli spazi e sostituire ogni istanza con un unico spazio?

risposta

53

Questo è un caso in cui le espressioni regolari funzionano bene, perché si vuole trattare l'intera classe di caratteri di spazio bianco della stessa e sostituire piste di qualsiasi combinazione di spazio bianco con un carattere di spazio unico. Quindi, se la stringa è memorizzato in s, allora si dovrebbe fare:

fixed_string = s.gsub(/\s+/, ' ') 
+1

Questa è la risposta corretta. E un bel nome, potrei aggiungere . :) –

8

si desidera che il metodo di compressione:

str.squeeze([other_str]*) → new_str 
Builds a set of characters from the other_str parameter(s) using the procedure described for String#count. Returns a new string where runs of the same character that occur in this set are replaced by a single character. If no arguments are given, all runs of identical characters are replaced by a single character. 

    "yellow moon".squeeze     #=> "yelow mon" 
    " now is the".squeeze(" ")   #=> " now is the" 
    "putters shoot balls".squeeze("m-z") #=> "puters shot balls" 
+1

Questo non è giusto, credo. Comprime solo le esecuzioni di schede in una singola scheda e le esecuzioni di nuove righe in una singola nuova riga. Mentre lo leggevo, la domanda è cercare un modo per sostituire le esecuzioni di qualsiasi combinazione di caratteri di spazi bianchi con un singolo carattere spaziale. – Chuck

+0

Peccato che 'String.squeeze' non accetti espressioni regolari come argomento. Volta se pensi che sarebbe una buona idea; Potrei inviare un PR. – the911s

+2

anche questo rimuove i duplicati, ad es. "class" diventa "clas", che potrebbe essere un deal breaker se si esegue questo su say html il metodo più appropriato (se in rails) sarebbe String # squish – engineerDave

3

La risposta selezionata non rimuoverà non-breaking space caratteri.

questo dovrebbe funzionare in 1.9:

fixed_string = s.gsub(/(\s|\u00A0)+/, ' ')

+0

Suppongo che l'OP volesse rimuovere spazi bianchi senza significato (es. Esecuzioni di più di un carattere di spazio bianco) per riordinare e ridurre la dimensione delle stringhe intese per HTML, dal momento che più caratteri di spazio bianco consecutivi vengono compressi in uno spazio dai browser Web comunque ... Vale la pena notare che gli spazi non infrangibili sono _non_ insignificanti in HTML, non vengono compressi, cioè probabilmente non li vuoi rimuovere – callum

4

Il problema con la soluzione più semplice gsub(/\s+/, ' ') è che è molto lento, in quanto sostituisce ogni spazio, anche se è singolo. Ma di solito c'è 1 spazio tra le parole e dovremmo correggere solo se ci sono 2 o più spazi bianchi in sequenza.

migliore soluzione è gsub(/[\r\n\t]/, ' ').gsub(/ {2,}/, ' ') - prima sbarazzarsi di spazi bianchi speciali e poi spremere spazi normali

def method1(s) s.gsub!(/\s+/, ' '); s end 
def method2(s) s.gsub!(/[\r\n\t]/, ' '); s.gsub!(/ {2,}/, ' '); s end 

Benchmark.bm do |x| 
    n = 100_000 
    x.report('method1') { n.times { method1("Lorem ipsum\n\n dolor \t\t\tsit amet, consectetur\n \n\t\n adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") } } 
    x.report('method2') { n.times { method2("Lorem ipsum\n\n dolor \t\t\tsit amet, consectetur\n \n\t\n adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") } } 
end;1 

#  user  system  total  real 
# method1 4.090000 0.010000 4.100000 ( 4.124844) 
# method2 1.590000 0.010000 1.600000 ( 1.611443) 
11

In Rails è possibile utilizzare String#squish, che è un active_support estensioni.

require 'active_support' 

s = <<-EOS 
1/2 cup 

      onion 
EOS 

s.squish 
# => 1/2 cup onion 
Problemi correlati