web-dev-qa-db-fra.com

Supprimer des caractères non-ASCII non imprimables d'une chaîne

Je reçois une entrée utilisateur comprenant des caractères non-ASCII et des caractères non imprimables, tels que 

\xc2d
\xa0
\xe7
\xc3\ufffdd
\xc3\ufffdd
\xc2\xa0
\xc3\xa7
\xa0\xa0

par exemple:

email : [email protected]\xa0\xa0
street : 123 Main St.\xc2\xa0

sortie désirée:

  email : [email protected]
  street : 123 Main St.

Quel est le meilleur moyen de les supprimer en utilisant Java?
J'ai essayé ce qui suit, mais cela ne semble pas fonctionner

public static void main(String args[]) throws UnsupportedEncodingException {
        String s = "abc@gmail\\xe9.com";
        String email = "[email protected]\\xa0\\xa0";

        System.out.println(s.replaceAll("\\P{Print}", ""));
        System.out.println(email.replaceAll("\\P{Print}", ""));
    }

Sortie

abc@gmail\xe9.com
[email protected]\xa0\xa0
14
daydreamer

Vos exigences ne sont pas claires. Tous les caractères d'une variable String Java sont des caractères Unicode. Par conséquent, si vous les supprimez, vous resterez avec une chaîne vide. Je suppose que ce que vous voulez dire, c'est que vous voulez supprimer tous les caractères non-ASCII, non imprimables.

String clean = str.replaceAll("\\P{Print}", "");

Ici, \p{Print}représente une classe de caractères POSIX pour les caractères imprimables ASCII, alors que \P{Print} est le complément de cette classe. Avec cette expression, tous les caractères qui sont not printable ASCII sont remplacés par la chaîne vide. (La barre oblique inverse supplémentaire est due au fait que \ démarre une séquence d'échappement en chaînes de caractères.)


Apparemment, tous les caractères saisis sont en réalité ASCII caractères représentant un codage imprimable de caractères non imprimables ou non ASCII. Mongo ne devrait pas avoir de problèmes avec ces chaînes, car elles ne contiennent que des caractères ASCII simples et imprimables. 

Tout cela me semble un peu louche. Je crois que les données contiennent en réalité des caractères non imprimables et non ASCII, et qu'un autre composant (comme un cadre de journalisation) les remplace par une représentation imprimable. Dans vos tests simples, vous ne parvenez pas à traduire la représentation imprimable dans la chaîne d'origine, de sorte que vous croyez à tort que la première expression régulière ne fonctionne pas. 

C'est ce que je suppose, mais si j'ai mal interprété la situation et que vous avez vraiment besoin d'éliminer les échappements \xHH littéraux, vous pouvez le faire avec l'expression régulière suivante.

String clean = str.replaceAll("\\\\x\\p{XDigit}{2}", "");

La documentation de l'API pour la classe Pattern réussit à répertorier toute la syntaxe prise en charge par la bibliothèque regex de Java. Pour plus de précisions sur la signification de toute la syntaxe, j'ai trouvé le site Regular-Expressions.info très utile.

33
erickson

Avec Google Guava '/ CharMatcher , vous pouvez supprimer tous les caractères non imprimables et conserver tous les caractères ASCII (en supprimant les accents), comme ceci:

String printable = CharMatcher.INVISIBLE.removeFrom(input);
String clean = CharMatcher.ASCII.retainFrom(printable);

Vous ne savez pas vraiment si c'est ce que vous voulez, mais cela supprime tout élément exprimé sous forme de séquences d'échappement dans les exemples de données de votre question.

14
Philipp Reichart

Je sais qu'il est peut-être tard, mais pour référence future:

String clean = str.replaceAll("\\P{Print}", "");

Supprime tous les caractères non imprimables, mais cela inclut \n (saut de ligne), \t (tabulation) et \r (retour chariot), et vous souhaitez parfois conserver ces caractères.

Pour ce problème, utilisez une logique inversée:

String clean = str.replaceAll("[^\\n\\r\\t\\p{Print}]", "");
10
Ivan Pavić

Vous pouvez essayer ce code:

public String cleanInvalidCharacters(String in) {
    StringBuilder out = new StringBuilder();
    char current;
    if (in == null || ("".equals(in))) {
        return "";
    }
    for (int i = 0; i < in.length(); i++) {
        current = in.charAt(i);
        if ((current == 0x9)
                || (current == 0xA)
                || (current == 0xD)
                || ((current >= 0x20) && (current <= 0xD7FF))
                || ((current >= 0xE000) && (current <= 0xFFFD))
                || ((current >= 0x10000) && (current <= 0x10FFFF))) {
            out.append(current);
        }

    }
    return out.toString().replaceAll("\\s", " ");
}

Cela fonctionne pour moi pour supprimer les caractères non valides de String.

3
Paulius Matulionis

Vous pouvez utiliser Java.text.normalizer

1
exception

Entrée => " Ceci \ u7279 texte \ u7279 est ce dont j'ai besoin " Sortie => " Ce texte est ce dont j'ai besoin "

Si vous essayez de supprimer les caractères Unicode d'une chaîne comme ci-dessus, ce code fonctionnera

Pattern unicodeCharsPattern = Pattern.compile("\\\\u(\\p{XDigit}{4})");
Matcher unicodeMatcher = unicodeChars.matcher(data);
String cleanData = null;
if (unicodeMatcher.find()) {
    cleanData = unicodeMatcher.replaceAll("");
}
0