Op De Cirkel está quase certo. Sua sugestão funcionará na maioria dos casos:
myString.replaceAll("\\p{C}", "?");
Mas se myString
pode conter pontos de código não BMP, então é mais complicado. \p{C}
contém os pontos de código substitutos de \p{Cs}
. O método de substituição acima corromperá os pontos de código não BMP, às vezes substituindo apenas metade do par substituto. É possível que seja um bug do Java em vez do comportamento pretendido.
Usar as outras categorias constituintes é uma opção:
myString.replaceAll("[\\p{Cc}\\p{Cf}\\p{Co}\\p{Cn}]", "?");
No entanto, personagens substitutos solitários que não fazem parte de um par (cada personagem substituto tem um ponto de código atribuído) não serão removidos. Uma abordagem não regex é a única maneira que conheço para lidar adequadamente com \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;
}
}