Czy ktokolwiek ma jakiś kod pod ręką, że centrum obcina łańcuch w Ruby on Rails?Jak wyciąć łańcuch w środku?
Coś takiego: Np .: "Witaj świecie, jak się masz?" => "Hel ... ty?"
Czy ktokolwiek ma jakiś kod pod ręką, że centrum obcina łańcuch w Ruby on Rails?Jak wyciąć łańcuch w środku?
Coś takiego: Np .: "Witaj świecie, jak się masz?" => "Hel ... ty?"
Oto zmodyfikowana wersja odpowiedź Mike Woodhouse jest. Wymaga dwóch opcjonalnych parametrów: minimalnej długości, aby ciąg był elipsyzowany, a długość krawędzi.
class String
def ellipsisize(minimum_length=4,edge_length=3)
return self if self.length < minimum_length or self.length <= edge_length*2
edge = '.'*edge_length
mid_length = self.length - edge_length*2
gsub(/(#{edge}).{#{mid_length},}(#{edge})/, '\1...\2')
end
end
"abc".ellipsisize #=> "abc"
"abcdefghi".ellipsisize #=> "abcdefghi"
"abcdefghij".ellipsisize #=> "abc...hij"
"abcdefghij".ellipsisize(4,4) #=> "abcd...ghij"
"Testing all paramas and checking them!".ellipsisize(6,5) #=> "Testi...them!"
Duh, zmieniłem moje, a następnie zauważyłem, że zrobiłeś bardziej kompletną wersję. Miły. +1 –
Może powinniśmy przesłać go jako łatkę do zespołu Rails? – khelll
Bardzo skomplikowane. Zobacz moją odpowiedź na znacznie prostsze rozwiązanie z wykorzystaniem istniejących pomocników 'String' Rails. –
Ponieważ nie określono liczby znaków, które mają zostać obcięte, przyjmuję (z przykładu), że należy obcinać ciągi, których długość jest większa niż sześć. Następnie możesz użyć czegoś takiego:
s = "Hello World, how are you?"
s = s[0, 3] + "..." + s[-3, 3] if s.length > 9
=> "Hel...ou?"
Wystarczy dostosować zakresy, aby skrócić kolejność znaków.
DigitalRoss ma rację co do "> 9" zamiast "> 6" - jeśli masz ciąg o długości 7, dodajesz dwa znaki _i_ utracone informacje. –
Masz rację, zapomniałeś policzyć rozmiar elipsy. Naprawiono to teraz. –
Oto moja propozycja:
s[3...-4] = "..." if s.length > 9
Naprawdę nie lubię edycji na miejscu, ponieważ nie wiesz, skąd pochodzi ciąg. Co jeśli jest to atrybut modelu i później zadzwonisz zapisać? –
Tak, '(s = s.dup) [3 ...- 4] = ...' może być lepsze, a nawet funkcjonalne w punkcie widzenia "jak czarna skrzynka". Słuszna uwaga. – DigitalRoss
Prawdopodobnie miałeś na myśli (t = s.dup) ... tam –
Jak o wersji Regex:
class String
def ellipsisize
gsub(/(...).{4,}(...)/, '\1...\2')
end
end
"abc".ellipsisize #=> "abc"
"abcdefghi".ellipsisize #=> "abcdefghi"
"abcdefghij".ellipsisize #=> "abc...hij"
EDIT: jak sugeruje się w komentarzach, długość parametryzowane (i przy użyciu innej notacji regex tylko dla cholery z nim)
class String
def ellipsisize(len = 9)
len = 9 unless len > 9 # assumes minimum chars at each end = 3
gsub(%r{(...).{#{len-5},}(...)}, '\1...\2')
end
end
tak ...
"abcdefghij".ellipsisize #=> "abc...hij"
ale możemy też:
"abcdefghij".ellipsisize(10) #=> "abcdefghij"
Rozwiązuje to problemy zarówno z rozwiązaniami DigitalRoss, jak i JG. +1 –
Bardzo fajny, choć przejąłbym go tylko dla nazwy metody. – Telemachus
Fajnie, choć będzie lepiej, jeśli można go zmodyfikować, aby zaakceptować parametr długości łańcucha, aby zastosować obcięcie tylko wtedy, gdy ciąg jest dłuższy niż ta długość. – khelll
class String
# https://gist.github.com/1168961
# remove middle from strings exceeding max length.
def ellipsize(options={})
max = options[:max] || 40
delimiter = options[:delimiter] || "..."
return self if self.size <= max
remainder = max - delimiter.size
offset = remainder/2
(self[0,offset + (remainder.odd? ? 1 : 0)].to_s + delimiter + self[-offset,offset].to_s)[0,max].to_s
end unless defined? ellipsize
end
dodałem opcję położenia metody Grosser za:
def ellipsize(str, options={})
max = options[:max] || 40
delimiter = options[:delimiter] || "..."
position = options[:position] || 0.8
return str if str.size <= max
remainder = max - delimiter.size
offset_left = remainder * position
offset_right = remainder * (1 - position)
(str[0,offset_left + (remainder.odd? ? 1 : 0)].to_s + delimiter + str[-offset_right,offset_right].to_s)[0,max].to_s
end
Jeśli chcesz pewną stałą długość niezależnie od długości łańcucha, można użyć Rails #truncate
:
s.truncate(100, omission: "...#{s.last(50)}")
To fantastyczne. Właśnie to szukałem. – Ossie
Zasługujesz na mój upominek. Tego właśnie szukam. – BartSabayton
Jeśli ciąg znaków wynosi na przykład 110, wiele znaków zostanie powtórzonych przed i po elipsie – collimarco
Jeśli chcesz ograniczyć długość łańcucha o bajtyzację i potrzebujesz obsługiwać kodowanie Unicode, Wymienione rozwiązania nie będą działać poprawnie.
Oto rozwiązanie, które wykorzystuje rozmiar bajtów i utrzymuje Unicode elementów tekstowych nienaruszony (które nie zawsze są takie same jak znaki Unicode ). Testowane w Ruby 1.8/1.9/2.0.
Można go ulepszyć, aby był bardziej wydajny w przypadku bardzo długich łańcuchów, które muszą zostać przycięte na znacznie mniejszych długościach.
Musisz zainstalować klejnot unicode.
require 'unicode'
# truncates a unicode string like:
# >> truncate_string_middle('12345678', 5)
# => "1...8"
def truncate_string_middle(str, limit, ellipsis='...')
raise "limit (#{limit}) must not be less than the ellipsis size (#{ellipsis.bytesize})" if limit < ellipsis.bytesize
return str if str.bytesize <= limit
chars = Unicode.text_elements(str)
split_point = (chars.size/2.0).ceil
front, back = chars[0...split_point], chars[split_point..-1]
pop_front = chars.size.odd?
# alternate between popping from the front and shifting from the back until it's small enough
while (front.join + ellipsis + back.join).bytesize > limit
if pop_front
front.pop
else
back.shift
end
pop_front = !pop_front
end
front.join + ellipsis + back.join
end
Innym sposobem:
class String
def middle_truncate(len)
return self if len >= size
return self[0...len] unless len > 4
half = len/2.0
(result = dup)[(half - 1.5).floor...(1.5 - half).floor] = '...'
result
end
end
Ma to tę dodatkową zaletę, jeśli tylko obcinanie rozmiarów strun < 5.
np. na jeszcze rozmiarze wyrażenie:
2.1.1 :001 > s = "123456789"
=> "123456789"
2.1.1 :002 > s.middle_truncate 21
=> "123456789"
2.1.1 :003 > s.middle_truncate 20
=> "123456789"
2.1.1 :004 > s.middle_truncate 19
=> "12345678...34567890"
2.1.1 :005 > s.middle_truncate 18
=> "1234567...34567890"
2.1.1 :006 > s.middle_truncate 5
=> "1...0"
2.1.1 :007 > s.middle_truncate 4
=> "1234"
i za ciąg nieparzystej wielkości:
2.1.1 :012 > s = "123456789"
=> "123456789"
2.1.1 :013 > s.middle_truncate 22
=> "123456789"
2.1.1 :014 > s.middle_truncate 21
=> "123456789"
2.1.1 :015 > s.middle_truncate 20
=> "12345678...345678901"
2.1.1 :016 > s.middle_truncate 19
=> "12345678...45678901"
2.1.1 :017 > s.middle_truncate 5
=> "1...1"
2.1.1 :018 > s.middle_truncate 4
=> "1234"
Jest to najprostszy sposób dla mnie:
def ellipsisize(text, minimum_length=12,edge_length=4)
leftover = text.length - minimum_length
edge_length = leftover if (edge_length > leftover && leftover >= 0)
edge_length = 0 if leftover < 0
return text.truncate(minimum_length) << text.last(edge_length)
end
Regards ludzie!
Ile znaków chcesz obciąć? –
Korzystanie z szyn wymaga znajomości pewnych tematów programowania pośredniego i języka Ruby. Dlatego nie rozumiem, jaki jest twój problem - jest naprawdę łatwy do wdrożenia. Niektórzy mogą spierać się o używanie helpera lub łatania małp "String", ale * rozwiązywanie * jest po prostu proste. – samuil