Op De Cirkel sebagian besar benar. Sarannya akan berhasil dalam banyak kasus:
myString.replaceAll("\\p{C}", "?");
Tetapi jika myString
mungkin berisi titik kode non-BMP maka itu lebih rumit. \p{C}
berisi titik kode pengganti \p{Cs}
. Metode penggantian di atas akan merusak titik kode non-BMP dengan terkadang hanya mengganti setengah dari pasangan pengganti. Mungkin ini adalah bug Java, bukan perilaku yang dimaksudkan.
Menggunakan kategori konstituen lainnya adalah salah satu pilihan:
myString.replaceAll("[\\p{Cc}\\p{Cf}\\p{Co}\\p{Cn}]", "?");
Namun, karakter pengganti tunggal yang bukan merupakan bagian dari pasangan (setiap karakter pengganti memiliki titik kode yang ditetapkan) tidak akan dihapus. Pendekatan non-regex adalah satu-satunya cara yang saya tahu untuk menangani dengan benar \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;
}
}