我收到的用户输入包括非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
答案 0 :(得分:39)
您的要求不明确。 Java String
中的所有字符都是Unicode字符,因此如果删除它们,您将留下一个空字符串。我假设您的意思是要删除任何非ASCII,不可打印的字符。
String clean = str.replaceAll("\\P{Print}", "");
此处,\p{Print}
represents a POSIX character class表示可打印的ASCII字符,而\P{Print}
是该类的补充。使用此表达式,不可打印ASCII的所有字符都将替换为空字符串。 (额外的反斜杠是因为\
在字符串文字中启动转义序列。)
显然,所有输入字符实际上都是ASCII字符,表示不可打印或非ASCII字符的可打印编码。 Mongo应该对这些字符串没有任何问题,因为它们只包含普通的可打印ASCII字符。
这对我来说听起来有点可疑。我认为发生的事情是数据确实包含非可打印和非ASCII字符,而另一个组件(如日志框架)正在用可打印的表示替换它们。在您的简单测试中,您无法将可打印表示转换回原始字符串,因此您错误地认为第一个正则表达式不起作用。
这是我的猜测,但是如果我误读了这种情况并且您确实需要删除文字\xHH
转义符,则可以使用以下正则表达式执行此操作。
String clean = str.replaceAll("\\\\x\\p{XDigit}{2}", "");
Pattern
类的API文档很好地列出了Java的regex库支持的所有语法。为了更详细地说明所有语法的含义,我发现Regular-Expressions.info site非常有用。
答案 1 :(得分:14)
使用Google Guava的CharMatcher
,您可以删除所有non-printable字符,然后保留所有ASCII字符(删除任何重音符号),如下所示:
String printable = CharMatcher.INVISIBLE.removeFrom(input);
String clean = CharMatcher.ASCII.retainFrom(printable);
不确定这是否是您真正想要的,但它会删除问题示例数据中表示为转义序列的任何内容。
答案 2 :(得分:10)
我知道可能会迟到,但将来会参考:
String clean = str.replaceAll("\\P{Print}", "");
删除所有不可打印的字符,但其中包含\n
(换行符),\t
(制表符)和\r
(回车),有时您想要保留这些字符。
对于该问题,请使用倒置逻辑:
String clean = str.replaceAll("[^\\n\\r\\t\\p{Print}]", "");
答案 3 :(得分:3)
您可以尝试以下代码:
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
删除无效字符。
答案 4 :(得分:1)
您可以使用java.text.normalizer
答案 5 :(得分:0)
输入=&gt; “此 \ u7279 文字 \ u7279 是我需要的” 输出=&gt; “此文字是我需要的”
如果您尝试从上面的字符串中删除Unicode字符,则此代码将起作用
Pattern unicodeCharsPattern = Pattern.compile("\\\\u(\\p{XDigit}{4})");
Matcher unicodeMatcher = unicodeChars.matcher(data);
String cleanData = null;
if (unicodeMatcher.find()) {
cleanData = unicodeMatcher.replaceAll("");
}