Op De Cirkel tiene razón. Su sugerencia funcionará en la mayoría de los casos:
myString.replaceAll("\\p{C}", "?");
Pero si myString
puede contener puntos de código que no son BMP, entonces es más complicado. \p{C}
contiene los puntos de código sustitutos de \p{Cs}
. El método de reemplazo anterior corrompe los puntos de código que no son BMP reemplazando a veces solo la mitad del par sustituto. Es posible que se trate de un error de Java en lugar de un comportamiento previsto.
Usar las otras categorías constituyentes es una opción:
myString.replaceAll("[\\p{Cc}\\p{Cf}\\p{Co}\\p{Cn}]", "?");
Sin embargo, los personajes sustitutos solitarios que no forman parte de un par (cada personaje sustituto tiene un punto de código asignado) no se eliminarán. Un enfoque sin expresiones regulares es la única forma que conozco de manejar correctamente \p{C}
:
StringBuilder newString = new StringBuilder(myString.length());
for (int offset = 0; offset < myString.length();)
{
int codePoint = myString.codePointAt(offset);
offset += Character.charCount(codePoint);
switch (Character.getType(codePoint))
{
case Character.CONTROL:
case Character.FORMAT:
case Character.PRIVATE_USE:
case Character.SURROGATE:
case Character.UNASSIGNED:
newString.append('?');
break;
default:
newString.append(Character.toChars(codePoint));
break;
}
}