97 votes

Comment remplacer les caractères Unicode non imprimables en Java ?

Les éléments suivants remplaceront les caractères de contrôle ASCII (abréviation de [\x00-\x1F\x7F] ) :

my_string.replaceAll("\\p{Cntrl}", "?");

Le texte suivant remplacera tous les caractères non imprimables ASCII (abréviation de [\p{Graph}\x20] ), y compris les caractères accentués :

my_string.replaceAll("[^\\p{Print}]", "?");

Toutefois, ni l'un ni l'autre ne fonctionne pour les chaînes Unicode. Quelqu'un connaît-il un bon moyen de supprimer les caractères non imprimables d'une chaîne unicode ?

2 votes

Juste un addendum : la liste des catégories générales d'Unicode peut être trouvée dans UAX #44

1 votes

1 votes

@Stewart : salut, avez-vous regardé les questions/réponses en dehors du titre ?!?

157voto

Op De Cirkel Points 8632
my_string.replaceAll("\\p{C}", "?");

En savoir plus Regex Unicode . java.util.regexPattern / String.replaceAll les soutient.

0 votes

Dans java 1.6 au moins, il n'y a pas de support pour eux. download.oracle.com/javase/6/docs/api/java/util/regex/ ...J'ai également essayé votre ligne, et en plus de manquer un backslash, elle ne fonctionne tout simplement pas.

0 votes

Ça marche : char c = 0xFFFA; String.valueOf(c).replaceAll("\\p{C}", "?"); également dans la javadoc pour le motif, regardez dans le fichier Support Unicode dit qu'il soutient les catégories

0 votes

Vous avez raison ! Je m'excuse. Je ne l'avais pas remarqué parce que j'ai dû ajouter les catégories Zl Zp car elles étaient la plupart du temps à l'origine des problèmes. Cela fonctionne parfaitement. Pourriez-vous s'il vous plaît faire une mini modification de votre post pour que je puisse le voter à nouveau ?

69voto

noackjr Points 81

Op De Cirkel a surtout raison. Sa suggestion fonctionnera dans la plupart des cas :

myString.replaceAll("\\p{C}", "?");

Mais si myString peut contenir des points de code non-BMP, alors c'est plus compliqué. \p{C} contient les points de code de substitution de \p{Cs} . La méthode de remplacement ci-dessus corrompt les points de code non-BMP en ne remplaçant parfois que la moitié de la paire de substituts. Il est possible qu'il s'agisse d'un bogue Java plutôt que d'un comportement voulu.

L'utilisation des autres catégories de constituants est une option :

myString.replaceAll("[\\p{Cc}\\p{Cf}\\p{Co}\\p{Cn}]", "?");

Cependant, les caractères de substitution solitaires qui ne font pas partie d'une paire (chaque caractère de substitution a un point de code attribué) ne seront pas supprimés. Une approche non-regex est le seul moyen que je connaisse pour traiter correctement les \p{C} :

StringBuilder newString = new StringBuilder(myString.length());
for (int offset = 0; offset < myString.length();)
{
    int codePoint = myString.codePointAt(offset);
    offset += Character.charCount(codePoint);

    // Replace invisible control characters and unused code points
    switch (Character.getType(codePoint))
    {
        case Character.CONTROL:     // \p{Cc}
        case Character.FORMAT:      // \p{Cf}
        case Character.PRIVATE_USE: // \p{Co}
        case Character.SURROGATE:   // \p{Cs}
        case Character.UNASSIGNED:  // \p{Cn}
            newString.append('?');
            break;
        default:
            newString.append(Character.toChars(codePoint));
            break;
    }
}

9voto

Ali Bagheri Points 632

Méthodes ci-dessous pour votre objectif

public static String removeNonAscii(String str)
{
    return str.replaceAll("[^\\x00-\\x7F]", "");
}

public static String removeNonPrintable(String str) // All Control Char
{
    return str.replaceAll("[\\p{C}]", "");
}

public static String removeSomeControlChar(String str) // Some Control Char
{
    return str.replaceAll("[\\p{Cntrl}\\p{Cc}\\p{Cf}\\p{Co}\\p{Cn}]", "");
}

public static String removeFullControlChar(String str)
{
    return removeNonPrintable(str).replaceAll("[\\r\\n\\t]", "");
}

8voto

Joachim Sauer Points 133411

Vous pouvez être intéressé par le Catégories Unicode "Autre, Contrôle" y éventuellement "Autre, format" (malheureusement, ce dernier semble contenir à la fois des caractères non imprimables et imprimables).

Dans les expressions régulières Java, vous pouvez les vérifier en utilisant \p{Cc} y \p{Cf} respectivement.

0 votes

Eh bien, dommage que les expressions java ne les aient pas, mais au moins j'ai la liste maintenant... c'est mieux que rien. merci

0voto

Diegolo Points 61

Jetez un coup d'œil à Junidecode bibliothèque

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X