Op De Cirkel ha perlopiù ragione. Il suo suggerimento funzionerà nella maggior parte dei casi:
myString.replaceAll("\\p{C}", "?");
Ma se myStringpotrebbe contenere codepoint non BMP, allora è più complicato. \p{C}contiene i codepoint surrogati di \p{Cs}. Il metodo di sostituzione sopra corromperà i codepoint non BMP sostituendo a volte solo metà della coppia surrogata. È possibile che questo sia un bug di Java piuttosto che un comportamento previsto.
L'utilizzo delle altre categorie costituenti è un'opzione:
myString.replaceAll("[\\p{Cc}\\p{Cf}\\p{Co}\\p{Cn}]", "?");
Tuttavia, i caratteri surrogati solitari che non fanno parte di una coppia (ogni carattere surrogato ha un codepoint assegnato) non verranno rimossi. Un approccio non regex è l'unico modo che conosco per gestire correttamente \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;
}
}