Op De Cirkel hầu như đúng. Đề xuất của anh ấy sẽ hoạt động trong hầu hết các trường hợp:
myString.replaceAll("\\p{C}", "?");
Nhưng nếu myString
có thể chứa các điểm mã không phải BMP thì nó phức tạp hơn. \p{C}
chứa mã thay thế của \p{Cs}
. Phương pháp thay thế ở trên sẽ làm hỏng các điểm mã không phải BMP bằng cách đôi khi chỉ thay thế một nửa cặp thay thế. Có thể đây là một lỗi Java chứ không phải là hành vi dự kiến.
Sử dụng các danh mục cấu thành khác là một tùy chọn:
myString.replaceAll("[\\p{Cc}\\p{Cf}\\p{Co}\\p{Cn}]", "?");
Tuy nhiên, các ký tự đại diện đơn lẻ không thuộc một cặp (mỗi ký tự đại diện có một điểm mã được chỉ định) sẽ không bị xóa. Phương pháp tiếp cận không regex là cách duy nhất tôi biết để xử lý đúng cách \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;
}
}