2013-06-05 10 views
5

Podane struny:Identyfikacja spacje vs inny znak przebiega ciąg

strs = [ 
    "foo", 
    " ", 
    "Hello \n there", 
    " Ooh, leading and trailing space! ", 
] 

Chcę prostą metodę identyfikujące wszystkie sąsiadujące serie białych i nie-białych znaków, aby wraz z czy prowadzony jest spacja czy nie:

strs.each{ |str| p find_whitespace_runs(str) } 
#=> [ {k:1, s:"foo"} ], 
#=> [ {k:0, s:" "} ], 
#=> [ {k:1, s:"Hello"}, {k:0, s:" \n "}, {k:1, s:"World"} ], 
#=> [ 
#=> {k:0, s:" "}, 
#=> {k:1, s:"Ooh,"}, 
#=> {k:0, s:" "}, 
#=> {k:1, s:"leading"}, 
#=> {k:0, s:" "}, 
#=> {k:1, s:"and"}, 
#=> {k:0, s:" "}, 
#=> {k:1, s:"trailing"}, 
#=> {k:0, s:" "}, 
#=> {k:1, s:"space!"}, 
#=> {k:0, s:" "}, 
#=> ] 

To prawie działa, ale zawiera jedną grupę wiodącą {k:0, s:""} gdy łańcuch nie zaczynają się od spacji:

def find_whitespace_runs(str) 
    str.split(/(\S+)/).map.with_index do |s,i| 
    {k:i%2, s:s} 
    end 
end 

Motywacja w świecie rzeczywistym: pisanie a syntax highlighter, która odróżnia odstępy od nie-białych znaków w kodzie odwzorowanym w inny sposób.

+2

Z ciekawości, dlaczego 0/1 zamiast falsy/truthy? –

+0

@WayneConrad Głównie dlatego, że sprawił, że wyniki trzeciego przykładu pasują do jednej linii :) Ponadto, jak widać w odnośniku z tego pytania, faktycznie nazywam 'each' i indeksuję do tablicy etykiet. – Phrogz

Odpowiedz

5
def find_whitespace_runs(str) 
    str.scan(/((\s+)|(\S+))/).map { |full, ws, nws| 
    { :k => nws ? 1 : 0, :s => full } 
    } 
end 
+0

Tricky! Chcę przetestować to trochę przed popełnieniem, ale myślę, że wygrasz złotą gwiazdę. – Phrogz

+0

Tak, to jest poprawne i tak samo szybkie jak mój obecny hack "podzielony". (I ma potencjał, aby być nieco lepszym pod względem pamięci.) Dobra robota. – Phrogz

+0

Perfect, perfetto, parfait, perfekt, perfecto, 完 ぺ き, 完美, 완전한! –

0

Działa, ale nie podoba mi się obecność unless empty? (i compact).

def find_whitespace_runs(str) 
    str.split(/(\S+)/).map.with_index do |s,i| 
    {k:i%2, s:s} unless s.empty? 
    end.compact 
end 

ja chętnie upvote żadnej odpowiedzi, które daje poprawne wyniki, i zaakceptuje żadnej odpowiedzi, która jest bardziej elegancki i wyraźnie bardziej wydajne.

Powiązane problemy