2013-05-06 9 views
7

Chcę wiedzieć, czy istnieje prosty sposób na uzyskanie tylko N symboli z ciągu bez przecinania całych słów.Zdobądź pierwsze znaki N z ciągu bez wycinania całych słów

Na przykład mam informacje o produktach i opisach produktów. Długość opisu wynosi od 70 do 500 symboli, ale chcę, aby wyświetlić tylko pierwszych 70 symboli, takich jak ten:

Coca-Cola to najpopularniejszy i najlepiej sprzedającym napój bezalkoholowy w historii, jak również najbardziej znana marka na świecie.

8 maja 2011 r. Coca-Cola obchodzi 125 rocznicę. Stworzona w 1886 w Atlancie w stanie Georgia przez dr. Johna S. Pembertona, Coca-Cola została po raz pierwszy oferowana jako napój fontannowy w aptece Jacoba poprzez zmieszanie syropu Coca-Cola z gazowaną wodą.

Więc metoda ciąg zwykły sub da mi:

Coca-Cola is the most popular and biggest-selling soft drink in histor 

i muszę metodę dostać tylko to:

Coca-Cola is the most popular and biggest-selling soft drink in ... 
+1

symbole? Masz na myśli "postacie"? –

Odpowiedz

3
s = "Coca-Cola is the most popular and biggest-selling soft drink in history, as well as the best-known brand in the world." 
s = s.split(" ").each_with_object("") {|x,ob| break ob unless (ob.length + " ".length + x.length <= 70);ob << (" " + x)}.strip 
#=> "Coca-Cola is the most popular and biggest-selling soft drink in" 
5

Metoda ta wykorzystuje wyrażenia regularnego, które chciwie chwyta do 70 znaków, a następnie dopasowuje spację lub koniec łańcucha, aby osiągnąć swój cel:

def truncate(s, max=70, elided = ' ...') 
    s.match(/(.{1,#{max}})(?:\s|\z)/)[1].tap do |res| 
    res << elided unless res.length == s.length 
    end  
end 

s = "Coca-Cola is the most popular and biggest-selling soft drink in history, as well as the best-known brand in the world." 
truncate(s) 
=> "Coca-Cola is the most popular and biggest-selling soft drink in ..." 
+0

Trudno mi zrozumieć to rozwiązanie. Czy możesz mi powiedzieć, co się dzieje? –

+0

@JakeSmith Dopasowujemy ciąg s, aby potencjalnie został obcięty względem wzorca regexp. Wzorzec składa się z klauzuli, aby łapczywie dopasować 1 do maksymalnych powtórzeń dowolnego znaku '(. {1, # {max}})' jako grupy przechwytywania, po której następuje klauzula, aby wykonać niezapisujące dopasowanie dowolnego spacji lub koniec ciągu '(?: \ s | \ z)'. '[1]' w wyniku meczu wyodrębnia pierwsze przechwytywanie. Jeśli to przechwycenie jest krótsze niż cały ciąg, dołącza elipsy. – dbenhur

+0

Uwaga: to może nie działać zgodnie z oczekiwaniami, gdy w pierwszych maks. Znakach nie ma spacji lub końca łańcucha. Na przykład. truncate (s, 3) daje w wyniku "ola ..." zamiast "Col ..." lub może po prostu "...". Jeśli w tym przypadku wolisz uzyskać pierwsze n znaków, poniżej znajdziesz inspirowane rozwiązanie. –

1
s[0..65].rpartition(" ").first << " ..." 

W swojej examle:

s = "Coca-Cola is the most popular and biggest-selling soft drink in history, as well as the best-known brand in the world."  
t = s[0..65].rpartition(" ").first << " ..." 
=> "Coca-Cola is the most popular and biggest-selling soft drink in ..." 
+0

Dobrze, ale jeśli zdanie nie ma miejsca, "..." zostanie zwrócone – justi

7

Wystarczy użyć obciąć z opcją separatora:

truncate("Once upon a time in a world far far away", length: 17) 
# => "Once upon a ti..." 
truncate("Once upon a time in a world far far away", length: 17, separator: ' ') 
# => "Once upon a..." 

zdobyć więcej informacji na stronie: truncate helper in rails API documentation

0

(Zainspirowany odpowiedź dbenhur, ale lepiej obsługuje przypadek, w którym nie ma białego spacji lub końca łańcucha w pierwszym maksimum znaków).

def truncate(s, options = { }) 
    options.reverse_merge!({ 
    max: 70, 
    elided: ' ...' 
    }); 

    s =~ /\A(.{1,#{options[:max]}})(?:\s|\z)/ 
    if $1.nil? then s[0, options[:max]] + options[:elided] 
    elsif $1.length != s.length then $1 + options[:elided] 
    else $1 
    end 
end 
0
b="Coca-Cola is the most popular and biggest-selling soft drink in history, as well " 

def truncate x 
a=x.split("").first(70).join 

w=a.split("").map!.with_index do |x,y| 
    if x!=" " 
     x=nil 
    else 
     x=y 
    end 
end 
w.compact! 
index=w.last 

x.split("").first(index).join+" ..." 
end 

truncate b 
Powiązane problemy