regex Java中使用的正则表达式“\\P{Print}”删除扩展拉丁字符[重复]

carvr3hs  于 2023-04-13  发布在  Java
关注(0)|答案(1)|浏览(90)

此问题已在此处有答案

How can I replace non-printable Unicode characters in Java?(9个回答)
5天前关闭。
此帖子5天前编辑并提交审核,未能重新打开帖子:
原始关闭原因未解决
我看到Java中的下面一行删除了扩展拉丁字符,这是不应该做的:

String finalStr = value.replaceAll("\\P{Print}", " ");

\\P{Print} regexp用于删除代码32以下的不可打印字符。但下面的扩展拉丁字符不是不可打印的,它们是可打印的。
Áéü œ, Š, Ÿ œ =〉, ,

String finalStr = value.replaceAll("\\P{Print}", " ");

在我的例子中,我需要删除所有不可打印的字符〈Code 32,但保留所有其他字符,包括Extended-Latin。

c6ubokkw

c6ubokkw1#

根据the documentation,默认情况下这些类仅适用于US-ASCII
具体而言:

\p{Lower}   A lower-case alphabetic character: [a-z]
\p{Upper}   An upper-case alphabetic character:[A-Z]
\p{Alpha}   An alphabetic character:[\p{Lower}\p{Upper}]
\p{Digit}   A decimal digit: [0-9]
\p{Alnum}   An alphanumeric character:[\p{Alpha}\p{Digit}]
\p{Graph}   A visible character: [\p{Alnum}\p{Punct}]
\p{Print}   A printable character: [\p{Graph}\x20]

把所有这些放在一起,\p{print}只匹配[a-zA-Z0-9\x20]

然而,在文档中,我们可以找到:

以下预定义字符类和POSIX字符类符合附录C的建议:指定UNICODE_CHARACTER_CLASS标志时Unicode正则表达式的兼容性属性。

\p{Cntrl}   A control character: \p{gc=Cc}

因此,请确保传递Pattern.UNICODE_CHARACTER_CLASS,并使用Pattern.compile("\\p{Cntrl}").matcher(value).replaceAll("")
看起来\p{Print}也可以工作,但是如果你特别想删除控制字符,Cntrl是正确的类。

演示

import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Main {  
  public static void main(String args[]) {
    // Control characters are 00 to 1F included, this has 3
    String value = "Áéü œ, Š, Ÿ œ\u0000\u0010\u001f";
    String needle = "\\p{Cntrl}";
    Pattern pattern = Pattern.compile(needle, Pattern.UNICODE_CHARACTER_CLASS);
    String result = pattern.matcher(value).replaceAll("");
    System.out.println(value.length()); // Prints 16
    System.out.println(result.length()); // Prints 13
  }
}

相关问题