Op De Cirkel ma w większości rację. Jego sugestia zadziała w większości przypadków:
myString.replaceAll("\\p{C}", "?");
Ale jeśli myString
może zawierać punkty kodowe inne niż BMP, jest to bardziej skomplikowane. \p{C}
zawiera zastępcze punkty kodowe \p{Cs}
. Powyższa metoda zamiany spowoduje uszkodzenie punktów kodowych innych niż BMP, czasami zastępując tylko połowę pary zastępczej. Możliwe, że jest to błąd języka Java, a nie zamierzone zachowanie.
Istnieje możliwość skorzystania z innych kategorii składników:
myString.replaceAll("[\\p{Cc}\\p{Cf}\\p{Co}\\p{Cn}]", "?");
Jednak pojedyncze znaki zastępcze niebędące częścią pary (każdy znak zastępczy ma przypisany punkt kodowy) nie zostaną usunięte. Podejście inne niż wyrażenia regularne to jedyny sposób, jaki znam, aby poprawnie obsługiwać \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;
}
}