2009-09-17 8 views
36

Metoda JDK na String.trim() jest dość naiwna i usuwa tylko znaki kontrolne ASCII.Jak poprawnie przyciąć białe spacje z ciągu znaków w języku Java?

Apache Commons 'StringUtils.strip() jest nieco lepszy, ale korzysta z JDK's Character.isWhitespace(), który doesn't recognize non-breaking space as whitespace.

Jaki byłby najbardziej kompletny, kompatybilny z Unicode, bezpieczny i odpowiedni sposób przycinania napisów w Javie?

Nawiasem mówiąc, czy istnieje lepsza biblioteka niż commons-lang, której powinienem używać do tego typu rzeczy?

Odpowiedz

55

Google dokonał guava-libraries dostępne niedawno. To may have czego szukasz:

CharMatcher.inRange('\0', ' ').trimFrom(str) 

jest równoważna String.trim(), ale można dostosować co do przycinania można znaleźć w JavaDoc.

Na przykład, ma its own definition of WHITESPACE, która różni się od JDK i jest zdefiniowany według najnowszego standardu Unicode, więc co trzeba może być zapisany jako:

CharMatcher.WHITESPACE.trimFrom(str) 
+2

Upvoted dokonywania czuję się jak kretyn – itsadok

+0

Dzięki za wskaźnik do guawy. Tęskniłem za tym. – CPerkins

+1

Porada: ["trimAndCollapseFrom"] (http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/CharMatcher.html#trimAndCollapseFrom (java.lang.CharSequence,% 20char)) przycina zewnętrzną część napisu, jednocześnie zastępując zduplikowane wartości wewnątrz ciągu. –

2

Zawsze uważałem, że trim działa całkiem dobrze w niemal każdym scenariuszu.

Jednakże, jeśli naprawdę chcesz dołączyć więcej znaków, można edytować metodę strip z commons-lang obejmuje nie tylko test na Character.isWhitespace, ale także dla Character.isSpaceChar który wydaje się czego brakuje. Mianowicie, następujące linie na stripStart i stripEnd odpowiednio:

  • while ((start != strLen) && Character.isWhitespace(str.charAt(start)))
  • while ((end != 0) && Character.isWhitespace(str.charAt(end - 1)))
7

Przysięgam widziałem tylko ten po Zamieściłem pytanie: Google właśnie wydało Guava, bibliotekę podstawowych narzędzi Java.

nie próbowałem tego jeszcze, ale z tego co mogę powiedzieć, to jest w pełni zgodny z Unicode:

String s = " \t testing \u00a0" 
s = CharMatcher.WHITESPACE.trimFrom(s); 
+2

Haha, podałem tę samą odpowiedź zaledwie 5 minut wcześniej, ale potem edytowałem ją, aby zawierała dokładny kod, którego potrzebujesz, i właśnie wtedy zobaczyłeś swój komentarz, że znalazłeś to sam. – CrazyCoder

2

To naprawdę trudne do zdefiniowania, co stanowi spacji. Czasami używam niełamliwych przestrzeni tylko po to, by się nie rozebrać. Trudno będzie więc znaleźć bibliotekę, która będzie robić dokładnie to, co chcesz.

Używam własnego wykończenia(), jeśli chcę przyciąć każdą białą przestrzeń. Oto funkcja używam do sprawdzenia dla białych przestrzeniach

public static boolean isWhitespace (int ch) 
    { 
    if (ch == ' ' || (ch >= 0x9 && ch <= 0xD)) 
     return true; 
    if (ch < 0x85) // short-circuit optimization. 
     return false; 
    if (ch == 0x85 || ch == 0xA0 || ch == 0x1680 || ch == 0x180E) 
     return true; 
    if (ch < 0x2000 || ch > 0x3000) 
     return false; 
    return ch <= 0x200A || ch == 0x2028 || ch == 0x2029 
     || ch == 0x202F || ch == 0x205F || ch == 0x3000; 
    } 
+9

Proszę podać te magiczne stałe. –

+6

ZZ Coder - mówicie: "trudno będzie znaleźć bibliotekę, aby zrobić dokładnie to, co chcesz". Nie prawda! Powiedzmy, że chcesz dopasować wszystkie spacje _except_ a \ u00a0 (spacja nierozdzielająca). Łatwe: CharMatcher.WHITESPACE.i (CharMatcher.isNot ('\ u00a0')). TrimFrom (input) –

+2

@ KevinBourrillion chciał tylko przesłać duże "podziękowania" dla 'CharMatcher.WHITESPACE'. 'String # trim()' zawodzi tak bardzo z Unicode. –

0

Zrobiłem małe zmiany dotyczące metody Java trim() i obsługuje metodę characters.This non-ASCII działa szybciej niż większość wdrożeń.

public static String trimAdvanced(String value) { 

     Objects.requireNonNull(value); 

     int strLength = value.length(); 
     int len = value.length(); 
     int st = 0; 
     char[] val = value.toCharArray(); 

     if (strLength == 0) { 
      return ""; 
     } 

     while ((st < len) && (val[st] <= ' ') || (val[st] == '\u00A0')) { 
      st++; 
      if (st == strLength) { 
       break; 
      } 
     } 
     while ((st < len) && (val[len - 1] <= ' ') || (val[len - 1] == '\u00A0')) { 
      len--; 
      if (len == 0) { 
       break; 
      } 
     } 


     return (st > len) ? "" : ((st > 0) || (len < strLength)) ? value.substring(st, len) : value; 
    } 
Powiązane problemy