2009-02-05 10 views

Odpowiedz

14

Użyj java.text.BreakIterator, coś takiego:

String s = ...; 
int number_chars = ...; 
BreakIterator bi = BreakIterator.getWordInstance(); 
bi.setText(s); 
int first_after = bi.following(number_chars); 
// to truncate: 
s = s.substring(0, first_after); 
+0

To wielkie dzięki, chociaż czy bi a. TruncateAt() byłyby zbyt trudne do zapytania? :) –

+0

Upewnij się, że test number_chars nie jest większy niż s.length(), w przeciwnym razie otrzymasz wyjątek. FYI, próbowałem edytować java, aby odzwierciedlić ten fakt, ale edycja została odrzucona. – mooreds

4

Można użyć wyrażenia regularnego

Matcher m = Pattern.compile("^.{0,10}\\b").matches(str); 
m.find(); 
String first10char = m.group(0); 
2

Przy pierwszym podejściu będzie w końcu o długości większej niż number_chars. Jeśli potrzebujesz dokładnego maksimum lub mniej, na przykład wiadomości na Twitterze, zobacz moją implementację poniżej.

Należy zauważyć, że podejście regexp używa spacji do rozdzielania słów, natomiast BreakIterator rozkłada wyrazy, nawet jeśli mają przecinki i inne znaki. Jest to bardziej pożądane.

Oto mój pełny funkcja:

/** 
    * Truncate text to the nearest word, up to a maximum length specified. 
    * 
    * @param text 
    * @param maxLength 
    * @return 
    */ 
    private String truncateText(String text, int maxLength) { 
     if(text != null && text.length() > maxLength) { 
      BreakIterator bi = BreakIterator.getWordInstance(); 
      bi.setText(text); 

      if(bi.isBoundary(maxLength-1)) { 
       return text.substring(0, maxLength-2); 
      } else { 
       int preceding = bi.preceding(maxLength-1); 
       return text.substring(0, preceding-1); 
      } 
     } else { 
      return text; 
     } 
    } 
0

Rozwiązanie z BreakIterator nie jest to proste, gdy łamiąc zdanie jest URL, przerywa URL nie bardzo miły sposób. Ja raczej użyłem roztworu kopalni:

public static String truncateText(String text, int maxLength) { 
    if (text != null && text.length() < maxLength) { 
     return text; 
    } 
    List<String> words = Splitter.on(" ").splitToList(text); 
    List<String> truncated = new ArrayList<>(); 
    int totalCount = 0; 
    for (String word : words) { 
     int wordLength = word.length(); 
     if (totalCount + 1 + wordLength > maxLength) { // +1 because of space 
      break; 
     } 
     totalCount += 1; // space 
     totalCount += wordLength; 
     truncated.add(word); 
    } 
    String truncResult = Joiner.on(" ").join(truncated); 
    return truncResult + " ..."; 
} 

Splitter/Joiner jest z guawy. Dodaję także ... na końcu mojego cas używania (można ommited).