Следующие символы заменят управляющие символы ASCII (сокращение для [\x00-\x1F\x7F]
):
my_string.replaceAll("\\p{Cntrl}", "?");
Следующее заменит все непечатаемые символы ASCII (сокращение для [\p{Graph}\x20]
), включая символы с диакритическими знаками:
my_string.replaceAll("[^\\p{Print}]", "?");
Однако ни то, ни другое не работает для строк Unicode. Есть ли у кого-нибудь хороший способ удалить непечатаемые символы из строки Unicode?
Ответы:
my_string.replaceAll("\\p{C}", "?");
Подробнее о регулярном выражении Unicode .
java.util.regexPattern
/String.replaceAll
поддерживает их.источник
char c = 0xFFFA; String.valueOf(c).replaceAll("\\p{C}", "?");
также в javadoc for pattern look в разделе поддержки Unicode говорится, что он поддерживает категорииs.replaceAll("[\\p{C}\\p{Z}]", "")
подойдет для васreplaceAll("[^\\u0000-\\uFFFF]", "")
но безуспешноОп Де Сиркель в основном прав. Его предложение сработает в большинстве случаев:
Но если он
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); // Replace invisible control characters and unused code points switch (Character.getType(codePoint)) { case Character.CONTROL: // \p{Cc} case Character.FORMAT: // \p{Cf} case Character.PRIVATE_USE: // \p{Co} case Character.SURROGATE: // \p{Cs} case Character.UNASSIGNED: // \p{Cn} newString.append('?'); break; default: newString.append(Character.toChars(codePoint)); break; } }
источник
Возможно, вас заинтересуют категории Unicode «Другое, Контроль» и, возможно, «Другое, Формат» (к сожалению, последний, похоже, содержит как непечатаемые, так и печатные символы).
В регулярных выражениях Java вы можете проверить их, используя
\p{Cc}
и\p{Cf}
соответственно.источник
методы удара для вашей цели
public static String removeNonAscii(String str) { return str.replaceAll("[^\\x00-\\x7F]", ""); } public static String removeNonPrintable(String str) // All Control Char { return str.replaceAll("[\\p{C}]", ""); } public static String removeSomeControlChar(String str) // Some Control Char { return str.replaceAll("[\\p{Cntrl}\\p{Cc}\\p{Cf}\\p{Co}\\p{Cn}]", ""); } public static String removeFullControlChar(String str) { return removeNonPrintable(str).replaceAll("[\\r\\n\\t]", ""); }
источник
Я использовал для этого эту простую функцию:
private static Pattern pattern = Pattern.compile("[^ -~]"); private static String cleanTheText(String text) { Matcher matcher = pattern.matcher(text); if ( matcher.find() ) { text = text.replace(matcher.group(0), ""); } return text; }
Надеюсь, это будет полезно.
источник
Основываясь на ответах Op De Cirkel и noackjr , для общей очистки строк я делаю следующее: 1. обрезка начальных или конечных пробелов, 2. dos2unix, 3. mac2unix, 4. удаление всех «невидимых символов Unicode», кроме пробелов:
myString.trim.replaceAll("\r\n", "\n").replaceAll("\r", "\n").replaceAll("[\\p{Cc}\\p{Cf}\\p{Co}\\p{Cn}&&[^\\s]]", "")
Протестировано с помощью Scala REPL.
источник
Я предлагаю удалить непечатаемые символы, как показано ниже, вместо их замены.
private String removeNonBMPCharacters(final String input) { StringBuilder strBuilder = new StringBuilder(); input.codePoints().forEach((i) -> { if (Character.isSupplementaryCodePoint(i)) { strBuilder.append("?"); } else { strBuilder.append(Character.toChars(i)); } }); return strBuilder.toString(); }
источник
Я переделал код для номеров телефонов +9 (987) 124124 Извлечение цифр из строки в Java
public static String stripNonDigitsV2( CharSequence input ) { if (input == null) return null; if ( input.length() == 0 ) return ""; char[] result = new char[input.length()]; int cursor = 0; CharBuffer buffer = CharBuffer.wrap( input ); int i=0; while ( i< buffer.length() ) { //buffer.hasRemaining() char chr = buffer.get(i); if (chr=='u'){ i=i+5; chr=buffer.get(i); } if ( chr > 39 && chr < 58 ) result[cursor++] = chr; i=i+1; } return new String( result, 0, cursor ); }
источник