Как правильно обрезать пробелы из строки в Java?

Метод JDK String.trim() довольно наивен и только удаляет управляющие символы ascii.

Apache Commons ' StringUtils.strip() немного лучше, но использует JDK Character.isWhitespace(), который не распознает неразрывное пространство как пробел.

Итак, что было бы самым полным, совместимым с Unicode, безопасным и правильным способом обрезать строку на Java?

И, кстати, есть ли лучшая библиотека, чем commons-lang которую я должен использовать для такого рода вещей?

Ответ 1

Google недавно сделал guava-libraries. может иметь, что вы ищете:

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

эквивалентен String.trim(), но вы можете настроить то, что нужно обрезать, обратиться к JavaDoc.

Например, он имеет собственное определение WHITESPACE, которое отличается от JDK и определяется в соответствии с последним стандартом Unicode, поэтому то, что вы потребность может быть записана как:

CharMatcher.WHITESPACE.trimFrom(str)

Ответ 2

Клянусь, я видел это только после того, как я опубликовал вопрос: Google только что выпустил Guava, библиотеку основных утилит Java.

Я еще не пробовал это, но из того, что я могу сказать, это полностью совместимо с Unicode:

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

Ответ 3

Я всегда находил, что trim работает очень хорошо практически для каждого сценария.

Однако, если вы действительно хотите включить больше символов, вы можете отредактировать strip метод из commons-lang, чтобы включить не только тест для Character.isWhitespace, но также и для Character.isSpaceChar, который, кажется, отсутствует. А именно, следующие строки в stripStart и stripEnd соответственно:

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

Ответ 4

Трудно определить, что представляет собой пробелы. Иногда я использую непробиваемые пространства просто для того, чтобы убедиться, что он не раздевается. Поэтому будет сложно найти библиотеку, чтобы сделать именно то, что вы хотите.

Я использую свою собственную trim(), если я хочу обрезать каждое пустое пространство. Вот функция, которую я использую для проверки пробелов,

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

Ответ 5

Я немного изменил метод java trim(), и он поддерживает символы, отличные от ascii. Этот метод работает быстрее, чем большинство реализаций.

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

Ответ 6

Это обрабатывает символы Unicode и не требует дополнительных библиотек:

String trimmed = original.replaceAll ("^\\p{IsWhite_Space}+|\\p{IsWhite_Space}+$", "");

Небольшая ошибка в том, что есть некоторые связанные пробельные символы без символьного символа Unicode "WSpace = Y", которые перечислены в Википедии. Вероятно, это не вызовет проблемы, но вы также можете легко добавить их в класс символов.

При использовании almson-regex регулярное выражение будет выглядеть так:

String trimmed = original.replaceAll (either (START_BOUNDARY + oneOrMore (WHITESPACE), oneOrMore (WHITESPACE) + END BOUNDARY), "");

и включать более релевантные из пробелов, отличных от Unicode.