2009-09-17 75 views
36

Phương thức String.trim() của JDK khá ngây thơ và chỉ loại bỏ các ký tự điều khiển ascii.Cách cắt đúng khoảng trắng từ một chuỗi trong Java?

Apache Commons 'StringUtils.strip() tốt hơn một chút, nhưng sử dụng số Character.isWhitespace() của JDK, doesn't recognize non-breaking space as whitespace.

Vì vậy, cách nào là cách hoàn chỉnh nhất, tương thích Unicode, an toàn và phù hợp để cắt chuỗi trong Java?

Và tình cờ, có thư viện nào tốt hơn commons-lang mà tôi nên sử dụng cho loại nội dung này không?

Trả lời

55

Google đã làm guava-libraries sẵn thời gian gần đây. Nó may have những gì bạn đang tìm kiếm:

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

tương đương với String.trim(), nhưng bạn có thể tùy chỉnh những gì để cắt, hãy tham khảo javadoc.

Ví dụ, nó có its own definition of WHITESPACE mà khác với JDK và được xác định theo tiêu chuẩn Unicode mới nhất, vì vậy những gì bạn cần có thể được viết như sau:

CharMatcher.WHITESPACE.trimFrom(str) 
+2

upvoted đã làm cho tôi cảm thấy như một kẻ ngớ ngẩn – itsadok

+0

Cảm ơn các con trỏ đến ổi. Tôi đã bỏ lỡ điều đó. – CPerkins

+1

Mẹo: ['trimAndCollapseFrom'] (http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/CharMatcher.html#trimAndCollapseFrom (java.lang.CharSequence,% 20char)) Trims bên ngoài của chuỗi trong khi cũng thay thế các giá trị trùng lặp bên trong chuỗi. –

2

Tôi luôn tìm thấy trim để hoạt động tốt cho hầu hết mọi trường hợp.

Tuy nhiên, nếu bạn thực sự muốn bao gồm các nhân vật nhiều hơn, bạn có thể chỉnh sửa các phương pháp strip từ commons-lang để bao gồm không chỉ là thử nghiệm cho Character.isWhitespace, mà còn cho Character.isSpaceChardường như là những gì còn thiếu. Cụ thể, các dòng sau vào stripStartstripEnd, tương ứng:

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

Tôi thề tôi chỉ thấy điều này sau khi tôi đăng tải câu hỏi: Google vừa phát hành Guava, một thư viện các tiện ích Java lõi.

Tôi đã không cố gắng này, nhưng từ những gì tôi có thể nói, đây là hoàn toàn Unicode compliant:

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

Haha, tôi đã cung cấp câu trả lời tương tự chỉ 5 phút trước đó, nhưng sau đó chỉnh sửa nó để bao gồm mã chính xác mà bạn cần sử dụng, và sau đó thấy nhận xét của bạn rằng bạn tự tìm thấy nó. – CrazyCoder

2

Thật sự rất khó để xác định những gì tạo khoảng trắng. Đôi khi tôi sử dụng không gian không thể phá vỡ chỉ để đảm bảo không gian bị lột. Vì vậy, thật khó để tìm một thư viện để làm chính xác những gì bạn muốn.

Tôi sử dụng cắt riêng của mình() nếu tôi muốn cắt mọi khoảng trắng. Đây là chức năng tôi sử dụng để kiểm tra cho các không gian màu trắng,

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

Hãy đặt tên cho các hằng số ma thuật đó .. –

+6

ZZ Coder - bạn nói, "thật khó để tìm một thư viện để làm chính xác những gì bạn muốn." Không đúng! Giả sử bạn muốn khớp tất cả khoảng trắng _except_ a \ u00a0 (khoảng trắng không phá vỡ). Dễ dàng: CharMatcher.WHITESPACE.and (CharMatcher.isNot ('\ u00a0')) .Từ đầu vào (đầu vào) –

+2

@KevinBourrillion chỉ muốn gửi qua một "cảm ơn" lớn cho 'CharMatcher.WHITESPACE'. 'String # trim()' không thành công với Unicode. –

0

tôi đã làm thay đổi chút về phương pháp java của trim() và nó hỗ trợ phương pháp characters.This phi ascii chạy nhanh hơn so với hầu hết các triển khai.

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; 
    } 
Các vấn đề liên quan