Как обрезать пробел из строки?

Я пишу эту функцию для приложения J2ME, поэтому у меня нет некоторых более продвинутых/современных классов Java, доступных для меня. Я получаю java.lang.ArrayIndexOutOfBoundsException по этому поводу. Так что, по-видимому, либо мне не нравится способ инициализации массива newChars, либо я что-то не так делаю при вызове System.arraycopy.

/*
 * remove any leading and trailing spaces
 */
public static String trim(String str) {
    char[] chars = str.toCharArray();
    int len = chars.length;
    // leading
    while ( (len > 0 ) && ( chars[0] == ' ' ) ) {
        char[] newChars = new char[] {}; // initialize empty array
        System.arraycopy(chars, 1, newChars, 0, len - 1);
        chars = newChars;
        len = chars.length;
    }
    // TODO: trailing
    return chars.toString();
}

Ответ 1

Простой способ обрезать начальные и конечные пробелы - вызвать String.trim(). Если вы просто хотите обрезать только начальные и конечные пробелы (а не все начальные и конечные пробелы), есть метод Apache commons, называемый StringUtils.strip(String, String), который может это сделать; вызовите его с " " в качестве второго аргумента.

Ваш попытанный код имеет ряд ошибок и в основном неэффективен. Если вы действительно хотите реализовать это самостоятельно, то вам следует:

  1. посчитать начальные пробелы
  2. считать символы пробела в конце
  3. если любое из значений не равно нулю, вызовите String.substring(from, end), чтобы создать новую строку, содержащую символы, которые вы хотите сохранить.

Этот подход позволяет избежать копирования любых символов 1.


1 - Actually, that depends on the implementation of [TG44]. For some implementations there will be no copying, for others a single copy is made. But either is an improvement on your approach, which entails a minimum of 2 copies, and more if there are any characters to trim.

Ответ 2

String.trim() очень старый, по крайней мере, до java 1.3. У вас этого нет?

Ответ 3

Apache StringUtils.strip - лучший ответ здесь, который работает со всеми ожидаемыми пробельными символами (не только пробел), и можно загрузить здесь:

Здесь соответствующий код вырван из этого исходного файла, чтобы реализовать его в своем собственном классе, если вы хотите, но на самом деле, просто скачайте и используйте StringUtils, чтобы получить больше отдачи! Обратите внимание, что вы можете использовать StringUtils.stripStart, чтобы обрезать любой начальный символ из строки Java.

public static final int INDEX_NOT_FOUND = -1

public static String strip(final String str) {
    return strip(str, null);
}

public static String stripStart(final String str, final String stripChars) {
    int strLen;
    if (str == null || (strLen = str.length()) == 0) {
        return str;
    }
    int start = 0;
    if (stripChars == null) {
        while (start != strLen && Character.isWhitespace(str.charAt(start))) {
            start++;
        }
    } else if (stripChars.isEmpty()) {
        return str;
    } else {
        while (start != strLen && stripChars.indexOf(str.charAt(start)) != INDEX_NOT_FOUND) {
            start++;
        }
    }
    return str.substring(start);
}

public static String stripEnd(final String str, final String stripChars) {
    int end;
    if (str == null || (end = str.length()) == 0) {
        return str;
    }

    if (stripChars == null) {
        while (end != 0 && Character.isWhitespace(str.charAt(end - 1))) {
            end--;
        }
    } else if (stripChars.isEmpty()) {
        return str;
    } else {
        while (end != 0 && stripChars.indexOf(str.charAt(end - 1)) != INDEX_NOT_FOUND) {
            end--;
        }
    }
    return str.substring(0, end);
}

public static String strip(String str, final String stripChars) {
    if (isEmpty(str)) {
        return str;
    }
    str = stripStart(str, stripChars);
    return stripEnd(str, stripChars);
}

Ответ 4

Прежде всего, что говорили другие о String.trim(). Действительно, не изобретайте велосипед.

Но для записи, что не так с вашим кодом, это то, что массивы Java не изменяются. Когда вы первоначально настроили свой целевой массив, вы создаете его как массив размера 0. Затем вы указываете System.arraycopy для заполнения символов len - 1. Это не сработает. Если вы хотите, чтобы он работал, вам нужно настроить массив следующим образом:

char[] newChars = new char[len - 1];

Но это удивительно неэффективно, перераспределяя и копируя новый массив каждый раз через цикл. Используйте три шага, о которых упоминал Стивен C, заканчивая substring.

Ответ 5

В JDK/11 теперь вы можете использовать API String.strip для возврата строки, значением которой является эта строка, с удалением всех начальных и конечных пробелов. Javadoc для того же:

/**
 * Returns a string whose value is this string, with all leading
 * and trailing {@link Character#isWhitespace(int) white space}
 * removed.
 * <p>
 * If this {@code String} object represents an empty string,
 * or if all code points in this string are
 * {@link Character#isWhitespace(int) white space}, then an empty string
 * is returned.
 * <p>
 * Otherwise, returns a substring of this string beginning with the first
 * code point that is not a {@link Character#isWhitespace(int) white space}
 * up to and including the last code point that is not a
 * {@link Character#isWhitespace(int) white space}.
 * <p>
 * This method may be used to strip
 * {@link Character#isWhitespace(int) white space} from
 * the beginning and end of a string.
 *
 * @return  a string whose value is this string, with all leading
 *          and trailing white space removed
 *
 * @see Character#isWhitespace(int)
 *
 * @since 11
 */
public String strip()

Примеры таких случаев: -

System.out.println("".strip());
System.out.println("  both  ".strip());
System.out.println("  leading".strip());
System.out.println("trailing  ".strip());

Ответ 6

Если вы не хотите использовать метод String.trim(), он может быть реализован, как показано ниже. Логика будет обрабатывать различные сценарии, такие как пространство, вкладка и другие специальные символы.

public static String trim(String str){
    int i=0;
    int j = str.length();
    char[] charArray = str.toCharArray();
    while((i<j) && charArray[i] <=' '){
        i++;
    }
    while((i<j) && charArray[j-1]<= ' '){
        j--;
    }
    return str.substring(i, j+1);

}

public static void main(String[] args) {
    System.out.println(trim("    abcd ght trip              "));

}

Ответ 7

Массив назначения newChars недостаточно велик, чтобы скопировать значения. Вам нужно инициализировать его до длины данных, которые вы собираетесь скопировать (так, длина - 1).

Ответ 8

Вы можете использовать Guava CharMatcher.

String outputString = CharMatcher.whitespace().trimFrom(inputString);

Примечание: это работает, потому что все пустые места находятся в BMP.