Удаление Java символов Unicode

Я получаю пользовательский ввод, включая символы Юникода, такие как

\xc2d
\xa0
\xe7
\xc3\ufffdd
\xc3\ufffdd
\xc2\xa0
\xc3\xa7
\xa0\xa0

например:

email : [email protected]\xa0\xa0
street : 123 Main St.\xc2\xa0

желаемый результат:

  email : [email protected]
  street : 123 Main St.

Каков наилучший способ их удаления с помощью Java?

Обновление: я пробовал следующее, но, похоже, не работает

public static void main(String args[]) throws UnsupportedEncodingException {
        String s = "[email protected]\\xe9.com";
        String email = "[email protected]\\xa0\\xa0";

        System.out.println(s.replaceAll("\\P{Print}", ""));
        System.out.println(email.replaceAll("\\P{Print}", ""));
    }

Выход

[email protected]\xe9.com
[email protected]\xa0\xa0

Ответ 1

Ваши требования не ясны. Все символы в Java String являются символами Юникода, поэтому, если вы удалите их, вы останетесь с пустой строкой. Я предполагаю, что вы имеете в виду, что вы хотите удалить любые символы, отличные от ASCII, непечатаемые.

String clean = str.replaceAll("\\P{Print}", "");

Здесь \p{Print} представляет класс символов POSIX для печатных символов ASCII, а \p{Print} является дополнением к этому классу. С помощью этого выражения все символы, которые не подлежат печати ASCII, заменяются пустой строкой. (Дополнительная обратная косая черта - это потому, что \ запускает escape-последовательность в строковых литералах.)


По-видимому, все входные символы являются фактически символами ASCII, которые представляют собой печатаемую кодировку непечатаемых или не-ASCII-символов. У Mongo не должно быть никаких проблем с этими строками, потому что они содержат только простые печатные символы ASCII.

Все это звучит немного подозрительно для меня. Я считаю, что данные действительно содержат непечатаемые и не-ASCII-символы, а другой компонент (например, фреймворк) заменяет их на печатное представление. В ваших простых тестах вы не можете перевести печатное представление обратно в исходную строку, поэтому вы ошибочно полагаете, что первое регулярное выражение не работает.

Это моя догадка, но если я неправильно понял ситуацию, и вам действительно нужно снять литеральные \xHH escape-последовательности, вы можете сделать это со следующим регулярным выражением.

String clean = str.replaceAll("\\\\x\\p{XDigit}{2}", "");

Документация API для класса Pattern делает хорошую работу по перечислению всего синтаксиса, поддерживаемого библиотекой regex Java. Для более подробной информации о том, что все синтаксис означает, я нашел Regular-Expressions.info сайт очень полезным.

Ответ 2

С Google Guava CharMatcher вы можете удалить любой непечатаемые, а затем сохраните все символы ASCII (сбросив любые акценты) следующим образом:

String printable = CharMatcher.INVISIBLE.removeFrom(input);
String clean = CharMatcher.ASCII.retainFrom(printable);

Не уверен, что то, что вы действительно хотите, но оно удаляет что-либо, выраженное как escape-последовательности в ваших данных образца вопроса.

Ответ 3

Я знаю, что это может быть поздно, но для справок в будущем:

String clean = str.replaceAll("\\P{Print}", "");

Удаляет все непечатаемые символы, но включает в себя \n (строка), \t (вкладка) и \r (возврат каретки), а иногда вы хотите сохранить эти символы.

Для этой проблемы используйте инвертированную логику:

String clean = str.replaceAll("[^\\n\\r\\t\\p{Print}]", "");

Ответ 4

Вы можете попробовать этот код:

public String cleanInvalidCharacters(String in) {
    StringBuilder out = new StringBuilder();
    char current;
    if (in == null || ("".equals(in))) {
        return "";
    }
    for (int i = 0; i < in.length(); i++) {
        current = in.charAt(i);
        if ((current == 0x9)
                || (current == 0xA)
                || (current == 0xD)
                || ((current >= 0x20) && (current <= 0xD7FF))
                || ((current >= 0xE000) && (current <= 0xFFFD))
                || ((current >= 0x10000) && (current <= 0x10FFFF))) {
            out.append(current);
        }

    }
    return out.toString().replaceAll("\\s", " ");
}

Он работает для меня, чтобы удалить недопустимые символы из String.

Ответ 5

Вы можете использовать java.text.normalizer

Ответ 6

Вход = > " Этот\u7279 текст\u7279 - это то, что мне нужно" Output = > " Этот текст - это то, что мне нужно"

Если вы пытаетесь удалить символы Unicode из строки, такой как выше, этот код будет работать

Pattern unicodeCharsPattern = Pattern.compile("\\\\u(\\p{XDigit}{4})");
Matcher unicodeMatcher = unicodeChars.matcher(data);
String cleanData = null;
if (unicodeMatcher.find()) {
    cleanData = unicodeMatcher.replaceAll("");
}