Chcę przyciąć ciąg, jeśli jego długość przekracza 10 znaków.
Załóżmy, że jeśli długość ciągu wynosi 12 ( String s="abcdafghijkl"), to nowy przycięty ciąg będzie zawierał "abcdefgh..".
Jak mogę to osiągnąć?
Chcę przyciąć ciąg, jeśli jego długość przekracza 10 znaków.
Załóżmy, że jeśli długość ciągu wynosi 12 ( String s="abcdafghijkl"), to nowy przycięty ciąg będzie zawierał "abcdefgh..".
Jak mogę to osiągnąć?
Odpowiedzi:
s = s.substring(0, Math.min(s.length(), 10));
Użycie w Math.minten sposób pozwala uniknąć wyjątku w przypadku, gdy ciąg jest już krótszy niż 10.
Uwagi:
Powyższe robi prawdziwe przycinanie. Jeśli faktycznie chcesz zastąpić ostatnie trzy (!) Znaki kropkami, jeśli jest obcięty, użyj Apache Commons StringUtils.abbreviate.
Może to zachowywać się niepoprawnie 1, jeśli ciąg znaków zawiera punkty kodowe Unicode poza BMP; np. emotikony. Aby uzyskać (bardziej skomplikowane) rozwiązanie, które działa poprawnie dla wszystkich punktów kodowych Unicode, zobacz rozwiązanie @ sibnick .
1 - Punkt kodowy Unicode, który nie znajduje się na płaszczyźnie 0 (BMP) jest reprezentowany jako „para zastępcza” (tj. Dwie charwartości) w pliku String. Ignorując to, możemy przyciąć do mniej niż 10 punktów kodowych lub (co gorsza) obciąć w środku pary zastępczej. Z drugiej strony, String.length()nie jest już idealną miarą długości tekstu Unicode, więc przycinanie na jego podstawie może być niewłaściwą rzeczą.
s = (s.length() > 10) ? s.substring(0,10) : s ;
StringUtils.abbreviatez biblioteki Apache Commons Lang może być Twoim przyjacielem:
StringUtils.abbreviate("abcdefg", 6) = "abc..."
StringUtils.abbreviate("abcdefg", 7) = "abcdefg"
StringUtils.abbreviate("abcdefg", 8) = "abcdefg"
StringUtils.abbreviate("abcdefg", 4) = "a..."
Commons Lang3 pozwala nawet ustawić niestandardowy ciąg jako znacznik zastępczy. W ten sposób możesz na przykład ustawić pojedynczy znak wielokropka.
StringUtils.abbreviate("abcdefg", "\u2026", 6) = "abcde…"
Jest to StringUtilsfunkcja Apache Commons, która to robi.
s = StringUtils.left(s, 10)
Jeśli len znaków nie jest dostępnych lub String ma wartość null, String zostanie zwrócony bez wyjątku. Jeśli len jest ujemne, zwracany jest pusty ciąg.
StringUtils.left (null, ) = null
StringUtils.left ( , -ve) = ""
StringUtils.left ("", *) = ""
StringUtils.left ("abc", 0) = ""
StringUtils.left (" abc ", 2) =" ab "
StringUtils.left (" abc ", 4) =" abc "
Dzięki uprzejmości: Steeve McCauley
Jak zwykle nikogo nie obchodzą zastępcze pary UTF-16. Zobacz o nich: Jakie są najczęściej używane znaki Unicode inne niż BMP? Nawet autorzy org.apache.commons / commons-lang3
Możesz zobaczyć różnicę między poprawnym kodem a zwykłym kodem w tym przykładzie:
public static void main(String[] args) {
//string with FACE WITH TEARS OF JOY symbol
String s = "abcdafghi\uD83D\uDE02cdefg";
int maxWidth = 10;
System.out.println(s);
//do not care about UTF-16 surrogate pairs
System.out.println(s.substring(0, Math.min(s.length(), maxWidth)));
//correctly process UTF-16 surrogate pairs
if(s.length()>maxWidth){
int correctedMaxWidth = (Character.isLowSurrogate(s.charAt(maxWidth)))&&maxWidth>0 ? maxWidth-1 : maxWidth;
System.out.println(s.substring(0, Math.min(s.length(), correctedMaxWidth)));
}
}
Lub możesz po prostu użyć tej metody na wypadek, gdybyś nie miał pod ręką StringUtils:
public static String abbreviateString(String input, int maxLength) {
if (input.length() <= maxLength)
return input;
else
return input.substring(0, maxLength-2) + "..";
}
System.out.println(abbreviateString("ABC\ud83d\udc3bDEF", 6));
Z Kotlin jest to tak proste, jak:
yourString.take(10)
Zwraca ciąg zawierający pierwsze n znaków z tego ciągu lub cały ciąg, jeśli ten ciąg jest krótszy.
Wydaje się, że podczas obcinania pytasz o znak wielokropka ( …) na ostatnim miejscu. Oto jednowierszowy sposób manipulowania ciągiem wejściowym.
String input = "abcdefghijkl";
String output = ( input.length () > 10 ) ? input.substring ( 0 , 10 - 1 ).concat ( "…" ) : input;
Zobacz, jak działa ten kod na IdeOne.com.
abcdefghi…
Możemy utworzyć jedną linijkę, używając operatora trójskładnikowego .
String input = "abcdefghijkl" ;
String output =
( input.length() > 10 ) // If too long…
?
input
.substring( 0 , 10 - 1 ) // Take just the first part, adjusting by 1 to replace that last character with an ellipsis.
.concat( "…" ) // Add the ellipsis character.
: // Or, if not too long…
input // Just return original string.
;
Zobacz, jak działa ten kod na IdeOne.com.
abcdefghi…
Funkcja Java Streams sprawia, że jest to interesujące, od wersji Java 9 i nowszych. Ciekawe, ale może nie najlepsze podejście.
Używamy raczej punktów kodowych niż charwartości. charTyp jest dziedzictwo i jest ograniczona do podzbioru wszystkich możliwych Unicode znaków.
String input = "abcdefghijkl" ;
int limit = 10 ;
String output =
input
.codePoints()
.limit( limit )
.collect( // Collect the results of processing each code point.
StringBuilder::new, // Supplier<R> supplier
StringBuilder::appendCodePoint, // ObjIntConsumer<R> accumulator
StringBuilder::append // BiConsumer<R,R> combiner
)
.toString()
;
Jeśli obcięto nadmiar znaków, zamień ostatni znak na wielokropek .
if ( input.length () > limit )
{
output = output.substring ( 0 , output.length () - 1 ) + "…";
}
Gdybym tylko mógł wymyślić sposób na połączenie linii strumienia z częścią „jeśli przekroczysz limit, wykonaj wielokropek”.
Oto rozwiązanie Kotlin
Jedna linia,
if (yourString?.length!! >= 10) yourString?.take(90).plus("...") else yourString
Tradycyjny,
if (yourString?.length!! >= 10) {
yourString?.take(10).plus("...")
} else {
yourString
}