2011-06-01 37 views
53

El siguiente reemplazará los caracteres de control ASCII (abreviatura de [\x00-\x1F\x7F]):¿Cómo puedo reemplazar caracteres Unicode no imprimibles en Java?

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

El siguiente reemplazará todos los caracteres ASCII no imprimible (la abreviatura de [\p{Graph}\x20]), incluyendo los caracteres acentuados:

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

Sin embargo , ninguno funciona para cadenas Unicode. ¿Alguien tiene una buena manera de eliminar los caracteres no imprimibles de una cadena Unicode?

+0

Tenga en cuenta que "no imprimible "e" invisible "son cosas diferentes. Los espacios en blanco (tab, space, newline, ...) son "invisibles" pero no imprimibles. –

+0

bien, me refiero a no imprimible – dagnelies

+1

Solo como una adición: la lista de categorías generales Unicode se puede encontrar en [UAX # 44] (http://unicode.org/reports/tr44/#GC_Values_Table) – McDowell

Respuesta

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

Ver más sobre Unicode regex. java.util.regexPattern/String.replaceAll los admite.

+0

En java 1.6 al menos, no hay soporte para ellos. http://download.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html ... También probé su línea, y además de perder una barra invertida, sencillamente no funciona. – dagnelies

+0

Esto funciona: 'char c = 0xFFFA; String.valueOf (c) .replaceAll ("\\ p {C}", "?"); 'También en el javadoc para ver el patrón en la sección ** Soporte de Unicode **, dice que admite las categorías –

+0

Estás ¡derecho! Me disculpo. No lo noté porque tuve que agregar las categorías de Zl Zp ya que esas eran principalmente la fuente de problemas. Funciona perfectamente ¿Podrías hacer una mini edición de tu publicación para poder votar nuevamente? – dagnelies

5

Usted puede estar interesado en el Unicode categories"Other, Control" y posiblemente "Other, Format" (por desgracia, este último parece contener caracteres no imprimibles tanto e imprimibles).

En las expresiones regulares de Java puede verificarlas usando \p{Cc} y \p{Cf} respectivamente.

+0

Bueno, las expresiones malas de Java no las tienen, pero al menos tengo la lista en este momento ... mejor que nada. gracias – dagnelies

38

Op De Cirkel es en su mayoría correcta. Su sugerencia funcionará en la mayoría de los casos:

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

Pero si myString puede contener puntos de código no-BMP entonces es más complicado. \p{C} contiene los puntos de código de sustitución de \p{Cs}. El método de reemplazo anterior corromperá los puntos de código que no sean BMP al reemplazar en ocasiones solo la mitad del par suplente. Es posible que esto sea un error de Java en lugar de un comportamiento previsto.

Uso de las otras categorías constituyente es una opción:

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

Sin embargo, no se eliminarán caracteres suplentes solitarias no parte de un par (cada carácter sustituto tiene un punto de código asignado). Un enfoque no-expresión regular es la única forma que conozco para manejar adecuadamente \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; 
    } 
} 
-2

he rediseñado el código de números de teléfono +9 (987) 124124 Extract digits from a string in Java

public static String stripNonDigitsV2(CharSequence input) { 
    if (input == null) 
     return null; 
    if (input.length() == 0) 
     return ""; 

    char[] result = new char[input.length()]; 
    int cursor = 0; 
    CharBuffer buffer = CharBuffer.wrap(input); 
    int i=0; 
    while (i< buffer.length() ) { //buffer.hasRemaining() 
     char chr = buffer.get(i); 
     if (chr=='u'){ 
      i=i+5; 
      chr=buffer.get(i); 
     } 

     if (chr > 39 && chr < 58) 
      result[cursor++] = chr; 
     i=i+1; 
    } 

    return new String(result, 0, cursor); 
} 
Cuestiones relacionadas