我如何在Java中replace不可打印的Unicode字符?

以下将取代ASCII控制字符( [\x00-\x1F\x7F]简写):

 my_string.replaceAll("\\p{Cntrl}", "?"); 

以下内容将replace所有ASCII非打印字符( [\p{Graph}\x20]简写),包括重音字符:

 my_string.replaceAll("[^\\p{Print}]", "?"); 

但是,对Unicodestring都不起作用。 有没有人有一个很好的方法来从unicodestring中删除不可打印的字符?

 my_string.replaceAll("\\p{C}", "?"); 

查看更多关于Unicode正则expression式 。 java.util.regexPattern / String.replaceAll支持它们。

Op De Cirkel大部分是正确的。 他的build议将在大多数情况下工作:

 myString.replaceAll("\\p{C}", "?"); 

但是,如果myString可能包含非BMP代码点,那么它更复杂。 \p{C}包含\p{Cs}的替代码点。 上面的replace方法会破坏非BMP代码点,有时只replace代理对的一半。 这可能是一个Java错误,而不是预期的行为。

使用其他组成类别是一个选项:

 myString.replaceAll("[\\p{Cc}\\p{Cf}\\p{Co}\\p{Cn}]", "?"); 

然而,孤立的代理字符不是一对(每个代理字符都有一个分配的代码点)的一部分将不会被删除。 非正则expression式方法是我知道正确处理\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 “其他,控制”和可能 “其他,格式”的Unicode类别感兴趣(不幸的是后者似乎包含不可打印和可打印的字符)。

在Java正则expression式中,您可以分别使用\p{Cc}\p{Cf}来检查它们。

我重新devise了电话号码+9(987)124124 从Java中的string中提取数字

  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 ); }