Dize uzunluğuna göre bir dizeyi kırpın


Yanıtlar:


262
s = s.substring(0, Math.min(s.length(), 10));

Math.minBöyle kullanmak , dizenin zaten daha kısa olduğu durumlarda bir istisnayı önler 10.


Notlar:

  1. Yukarıdakiler gerçek düzeltme yapar. Son üç (!) Karakteri kesilmişse noktalarla değiştirmek istiyorsanız, Apache Commons'ı kullanın StringUtils.abbreviate.

  2. String'iniz BMP dışında Unicode kod noktaları içeriyorsa, bu yanlış davranabilir 1 ; örneğin Emojiler. Tüm Unicode kod noktaları için doğru şekilde çalışan (daha karmaşık) bir çözüm için, @ sibnick'in çözümüne bakın .


1 - düzlem 0 (BMP) ile ilgili olmayan bir Unicode kod noktası, bir "taşıyıcı çifti" (yani iki olarak temsil edilir chardeğerler) String. Bunu görmezden gelerek, 10 kod noktasından daha azına veya (daha kötüsü) bir vekil çiftin ortasında kesebiliriz. Öte yandan, String.length()artık Unicode metin uzunluğunun ideal bir ölçüsü değildir, bu nedenle buna göre kırpma yapmak yanlış olabilir.


Math.min yerine, koşullu bir kontrol yapıp alt dizeyi yalnızca string maksimum ise gerekliyse yapamaz mıyız? örneğin:s = (s.length() > 10) ? s.substring(0,10) : s ;
rram

1
Evet tabiki yapabilirsin. Problemi çözmenin diğer yolları için diğer cevapları okuyun!
Stephen C

132

StringUtils.abbreviatedan Apache Commons Lang kitaplık arkadaşınız olabilir:

StringUtils.abbreviate("abcdefg", 6) = "abc..."
StringUtils.abbreviate("abcdefg", 7) = "abcdefg"
StringUtils.abbreviate("abcdefg", 8) = "abcdefg"
StringUtils.abbreviate("abcdefg", 4) = "a..."

Commons Lang3 , özel bir Stringi değiştirme işaretçisi olarak ayarlamaya bile izin verir. Bununla örneğin tek bir karakter üç nokta ayarlayabilirsiniz.

StringUtils.abbreviate("abcdefg", "\u2026", 6) = "abcde…"

5
Olabilir, ancak OP'nin sorusu "üç nokta" istemiyor.
Stephen C

9
@StephenC - Soru, bir üç noktaya çok benzeyen (3 yerine sadece 2 nokta) 10'luk bir uzunluk sınırı verildiğinde 8 karakter ve ardından 2 nokta gösterir. Ayrıca, bu soruyu bulan pek çok insanın bir üç noktayı yararlı bulması da muhtemeldir.
ToolmakerSteve

12
... ve elips istemiyorsanız, StringUtils.left () size yardımcı olabilir.
Superole

1
Bilginize, YATAY ELLIPSIS tek bir karakterdir, üç TAM DURDURMA karakteri değil:…
Basil Bourque

53

Bunu yapan bir Apache Commons StringUtilsişlevi vardır.

s = StringUtils.left(s, 10)

Len karakterleri mevcut değilse veya Dize boşsa, Dize istisnasız döndürülür. Len negatifse boş bir String döndürülür.

StringUtils.left (null, ) = null
StringUtils.left (
, -ve) = ""
StringUtils.left ("", *) = ""
StringUtils.left ("abc", 0) = ""
StringUtils.left (" abc ", 2) =" ab "
StringUtils.left (" abc ", 4) =" abc "

StringUtils.Left JavaDocs

Nezaket: Steeve McCauley


22

Her zamanki gibi UTF-16 vekil çiftlerini kimse umursamıyor. Onlara bakın: Gerçek kullanımda en yaygın BMP olmayan Unicode karakterler nelerdir? Org.apache.commons / commons-lang3'ün yazarları bile

Bu örnekte doğru kod ile normal kod arasındaki farkı görebilirsiniz:

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)));
    }
}

1
Apache commons ' jira'da
Ryan Quinn

10

s = s.length() > 10 ? s.substring(0, 9) : s;


16
İkinci alt dizge parametresi özeldir, bu nedenle bu yanıt String'i 9 karaktere böler.
emulcahy

8

Veya elinizde StringUtils yoksa bu yöntemi kullanabilirsiniz:

public static String abbreviateString(String input, int maxLength) {
    if (input.length() <= maxLength) 
        return input;
    else 
        return input.substring(0, maxLength-2) + "..";
}

Kodunuz benim için işe yaramadı. DeneyinSystem.out.println(abbreviateString("ABC\ud83d\udc3bDEF", 6));
T3rm1

4

Her ihtimale karşı, bir dizenin SON 10 karakterini kırpmanın ve saklamanın bir yolunu arıyorsanız.

s = s.substring(Math.max(s.length(),10) - 10);

3

Kotlin ile şu kadar basit:

yourString.take(10)

Bu dizeden ilk n karakteri içeren bir dize veya bu dize daha kısaysa tüm dizeyi döndürür.

belgeleme


1

tl; Dr.

Keserken , son sırada bir üç nokta ( ) karakteri istiyor gibisiniz. İşte giriş dizenizi işlemek için bir tek satırlık.

String input = "abcdefghijkl";
String output = ( input.length () > 10 ) ? input.substring ( 0 , 10 - 1 ).concat ( "…" ) : input;

Bu koda IdeOne.com'da canlı olarak bakın.

abcdefghi ...

Üçlü operatör

Üçlü operatörü kullanarak tek astar yapabiliriz .

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.
;

Bu koda IdeOne.com'da canlı olarak bakın.

abcdefghi ...

Java akışları

Java Streams tesisi, Java 9 ve sonraki sürümlerde bunu ilginç kılıyor. İlginç, ama belki de en iyi yaklaşım değil.

Değerler yerine kod noktaları kullanırız char. charTip miras ve sınırlıdır bir alt kümesi tüm olası Unicode karakterleri.

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()
        ;

Fazladan karakter kesilmişse, son karakteri bir üç nokta ile değiştirin .

if ( input.length () > limit )
{
    output = output.substring ( 0 , output.length () - 1 ) + "…";
}

Akım çizgisini "eğer aşırı limit varsa, elips yapın" kısmıyla bir araya getirmenin bir yolunu düşünebilseydim.


Hayır. Açıkça, ipin uzunluğu 11 veya daha fazla olursa ipin uzunluğunu kırpmak istiyor. Yeni bir AI sistemi üzerinde çalışıyor olmalısınız oO
JD333

1
@ JD333 Yorumunuz benden kaçıyor. Üç nokta da dahil olmak üzere 10 uzunluğa kadar kesmek tam olarak burada gösterdiğim şeydir.
Fesleğen Bourque

0
str==null ? str : str.substring(0, Math.min(str.length(), 10))

veya,

str==null ? "" : str.substring(0, Math.min(str.length(), 10))

Null ile çalışır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.