java中移除字符串中所有控制字符和不可见字符,应使用正则表达式[p{cc}p{cf}p{cn}]匹配并替换为空;若需保留常规空白符(如 、 、 、空格),则需额外排除或分步处理;apache commons lang的stringutils.stripcontrolchars()可简化操作但覆盖不全,必要时需补充正则。

Java 中移除字符串中所有控制字符和不可见字符,核心是识别并过滤 Unicode 中的控制字符(如 u0000–u001F、u007F、u200B–u200F、u2028–u2029 等)以及部分格式化字符(如零宽空格、行分隔符、段落分隔符等)。推荐使用正则表达式配合 String.replaceAll() 或 Pattern + Matcher 实现。
用正则匹配并移除常见控制与不可见字符
最常用且简洁的方式是使用 Unicode 属性类 p{C}(表示“Other”类别,涵盖控制字符、格式字符、私有区字符、未分配字符等),但需注意它范围偏大(会删掉一些合法的私有字符或符号)。更稳妥的做法是明确排除 p{Cn}(未分配)、p{Cc}(控制字符)、p{Cf}(格式字符)三类:
-
p{Cc}:ASCII 控制字符(u0000–u001F 和 u007F) -
p{Cf}:格式控制字符(如 u200B 零宽空格、u200C 零宽非连接符、u200D 零宽连接符、u2028 行分隔符、u2029 段落分隔符等) -
p{Cn}:未分配/未定义的 Unicode 码点(通常不应出现在正常文本中)
示例代码:
String clean = str.replaceAll("[\p{Cc}\p{Cf}\p{Cn}]", "");
保留空白符(空格、制表、换行)时的精细过滤
如果希望保留常规空白符(如空格 ' '、制表符 ' '、回车 '
'、换行 '
'),就不能直接用 s 或全量删 C 类,而应显式排除它们:
// 只删控制/格式/未分配字符,但保留
' ' 等可见空白
String clean = str.replaceAll("[\p{Cc}\p{Cf}\p{Cn}&&[^\t\n\r ]]", "");
或者更清晰地写成否定逻辑(推荐):
String clean = str.replaceAll("[\p{Cc}\p{Cf}\p{Cn}]", "")
.replaceAll("[^\p{Print}\t\n\r ]", ""); // 补删其他非打印但非 C 类的字符(可选)
使用 Apache Commons Lang(简化开发)
若项目已引入 commons-lang3,可用 StringUtils.stripControlChars() 快速处理:
import org.apache.commons.lang3.StringUtils;
String clean = StringUtils.stripControlChars(str); // 移除 p{Cc} 和部分 p{Cf}(如 u200B)
注意:该方法默认不处理所有 p{Cf}(例如 u2028/u2029),如有需要,仍建议结合正则补充:
String clean = StringUtils.stripControlChars(str)
.replaceAll("[\u2028\u2029\u200B-\u200F\u202A-\u202E]", "");
验证是否残留不可见字符
调试时可将字符串转为 Unicode 码点查看:
str.codePoints().forEach(cp ->
System.out.printf("U+%04X '%s'%s%n", cp,
Character.isISOControl(cp) ? "[CONTROL]" :
Character.isWhitespace(cp) ? "[WHITESPACE]" :
Character.isValidCodePoint(cp) ? String.valueOf((char)cp) : "[INVALID]"));
也可用在线工具(如 Unicode Viewer)粘贴字符串检查隐藏字符。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











