Оп Де Циркель переважно має рацію. Його пропозиція спрацює в більшості випадків:
myString.replaceAll("\\p{C}", "?");
Але якщо вони myString
можуть містити кодові точки, які не є BMP, то це складніше. \p{C}
містить сурогатні кодові точки \p{Cs}
. Наведений вище метод заміни призведе до пошкодження кодових точок, що не належать до BMP, іноді замінюючи лише половину сурогатної пари. Можливо, це помилка Java, а не передбачувана поведінка.
Варіант використання інших складових категорій:
myString.replaceAll("[\\p{Cc}\\p{Cf}\\p{Co}\\p{Cn}]", "?");
Однак поодинокі сурогатні символи, що не є частиною пари (кожному сурогатному символу присвоєна кодова точка), не видалятимуться. Нерегулярний підхід - це єдиний спосіб, яким я знаю, як правильно обробляти \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;
}
}