web-dev-qa-db-fra.com

Comment couper les espaces d'une chaîne?

J'écris cette fonction pour une application J2ME. Je ne dispose donc pas de certaines des classes Java les plus avancées/modernes. Je reçois Java.lang.ArrayIndexOutOfBoundsException à ce sujet. Donc, apparemment, soit il n'aime pas la façon dont j'ai initialisé le tableau newChars, ou je ne fais pas quelque chose correctement lorsque j'appelle 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();
}
26
user458442

Le moyen simple de réduire les espaces de début et de fin consiste à appeler String.trim() . Si vous voulez juste couper uniquement les espaces de début et de fin (plutôt que tous les espaces de début et de fin), il existe une méthode Apache commons appelée StringUtils.strip(String, String) qui peut le faire; appelez-le avec " " comme deuxième argument.

Votre code tenté contient un certain nombre de bogues et est fondamentalement inefficace. Si vous voulez vraiment implémenter cela vous-même, alors vous devriez:

  1. compter les premiers caractères d'espace
  2. compter les espaces de fin
  3. si le nombre est différent de zéro, appelez String.substring(from, end) pour créer une nouvelle chaîne contenant les caractères que vous souhaitez conserver.

Cette approche évite de copier des caractères1.


1 - En fait, cela dépend de la mise en oeuvre de String. Pour certaines implémentations, il n'y aura pas de copie, pour d'autres, une seule copie est faite. Mais l’une ou l’autre des améliorations est votre approche, qui implique un minimum de 2 copies, et plus si vous avez des personnages à couper.

37
Stephen C

String.trim() est très ancien, du moins à Java 1.3. Tu n'as pas ça?

14
Tony Ennis

Apache StringUtils.strip est la meilleure réponse ici, il fonctionne avec tous les caractères d’espace blanc attendus (pas seulement l’espace), et peut être téléchargé ici :

Voici le code approprié extrait de ce fichier source pour l'implémenter dans votre propre classe si vous le souhaitez, mais vraiment, téléchargez et utilisez StringUtils pour en avoir plus pour votre argent! Notez que vous pouvez également utiliser StringUtils.stripStart pour supprimer tout caractère principal d'une chaîne 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
Brad Parks

Avec JDK/11, vous pouvez maintenant utiliser l’APIString.strippour renvoyer une chaîne dont la valeur est cette chaîne, tous les espaces blancs de début et de fin étant supprimés. Le javadoc pour le même est:

/**
 * 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()

Les exemples de cas pour ceux-ci pourraient être: -

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

Tout d’abord, ce que d’autres ont dit à propos de String.trim(). Vraiment, ne réinventez pas la roue.

Mais pour mémoire, ce qui ne va pas avec votre code, c'est que les tableaux Java ne sont pas redimensionnables. Lorsque vous configurez initialement votre tableau cible, vous le créez en tant que tableau de taille 0. Vous dites ensuite à System.arraycopy d'insérer des caractères len - 1 à l'intérieur. Cela ne va pas au travail. Si vous voulez que cela fonctionne, vous devez configurer le tableau comme suit:

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

Mais c’est incroyablement inefficace de réaffecter et de copier un nouveau tableau à chaque fois dans la boucle. Utilisez les trois étapes mentionnées par Stephen C, en terminant par substring.

3
Daniel Martin

Si vous ne souhaitez pas utiliser la méthode String.trim (), vous pouvez la mettre en œuvre comme ci-dessous. La logique gérera différents scénarios tels que l'espace, la tabulation et d'autres caractères spéciaux.

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              "));

}
1
san242

Vous pouvez utiliser Guava CharMatcher .

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

Remarque: Cela fonctionne car les espaces sont dans le BMP.

0
sffc

Le tableau de destination newChars n'est pas assez grand pour contenir les valeurs copiées. Vous devez l'initialiser à la longueur des données que vous avez l'intention de copier (donc, longueur - 1).

0
Fredrick Pennachi