繁体   English   中英

从字符串中删除非 ASCII 不可打印字符

[英]Remove non-ASCII non-printable characters from a String

我得到用户输入,包括非 ASCII 字符和不可打印字符,例如

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

例如:

email : abc@gmail.com\xa0\xa0
street : 123 Main St.\xc2\xa0

所需的输出:

  email : abc@gmail.com
  street : 123 Main St.

使用 Java 删除它们的最佳方法是什么?
我尝试了以下方法,但似乎不起作用

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

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

输出

abc@gmail\xe9.com
abc@gmail.com\xa0\xa0

你的要求不是很清楚。 Java String中的所有字符都是 Unicode 字符,因此如果删除它们,您将得到一个空字符串。 我假设您的意思是您要删除任何非 ASCII、不可打印的字符。

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

此处, \\p{Print} 表示可打印 ASCII 字符的 POSIX 字符类,而\\P{Print}是该类的补充。 使用此表达式,所有不可打印的 ASCII 字符都将替换为空字符串。 (额外的反斜杠是因为\\在字符串文字中开始了一个转义序列。)


显然,所有输入字符实际上都是 ASCII 字符,表示不可打印或非 ASCII 字符的可打印编码。 Mongo 应该不会对这些字符串有任何问题,因为它们只包含普通的可打印 ASCII 字符。

这一切对我来说听起来有点可疑。 我相信正在发生的是,数据确实包含不可打印和非 ASCII 字符,另一个组件(如日志记录框架)正在用可打印表示替换这些字符。 在您的简单测试中,您未能将可打印表示转换回原始字符串,因此您错误地认为第一个正则表达式不起作用。

这是我的猜测,但如果我误读了情况并且您确实需要删除文字\\xHH转义\\xHH ,则可以使用以下正则表达式来完成。

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

Pattern类的 API 文档很好地列出了 Java 正则表达式库支持的所有语法。 有关所有语法含义的详细说明,我发现Regular-Expressions.info 站点非常有用。

使用Google GuavaCharMatcher ,您可以删除任何不可打印的字符,然后保留所有 ASCII 字符(删除任何重音符号),如下所示:

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

不确定这是否是您真正想要的,但它会删除问题示例数据中表示为转义序列的任何内容。

我知道现在可能已经晚了,但以供将来参考:

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

删除所有不可打印的字符,但包括\\n (换行)、 \\t (制表符)和\\r (回车),有时您想保留这些字符。

对于该问题,请使用反向逻辑:

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

你可以试试这个代码:

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删除无效字符。

您可以使用 java.text.normalizer

输入 => "这个\特文本\特是我需要的" 输出 => "这个文本是我需要的"

如果您尝试从上面的字符串中删除 Unicode 字符,则此代码将起作用

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM