Java-\ pL [\ x00- \ x7F] +正则表达式无法使用String.match获取非英文字符

时间:2019-06-02 12:21:05

标签: java regex

我需要验证保存在字符串中的名称,该名称可以使用\p{L}以任何语言加空格:

  

您可以使用\ p {L}

匹配属于“字母”类别的单个字符

我尝试使用String.matches,但是它无法匹配非英文字符,例如,即使是1个字符

String name = "อั";
boolean isMatch = name.matches("[\\p{L}]+")); // return false

我尝试使用/不使用方括号,为多个字母添加+,但始终无法匹配非英文字符

String.matches\p{L}一起使用是否有问题?

我也无法使用Pattern中建议的[\\x00-\\x7F]+

\p{ASCII} All ASCII:[\x00-\x7F]

5 个答案:

答案 0 :(得分:2)

您应该记住,Java正则表达式将字符串解析为Unicode代码单元(而不是代码点)的集合。 \p{L}匹配BMP平面中的任何Unicode字母,但不匹配其后加上变音符号的字母。

由于输入内容可以包含字母和变音符号,因此您至少应在字符类中同时使用\p{L}\p{M} Unicode属性类:

String regex = "[\\p{L}\\p{M}]+";

如果输入字符串可以包含用空格分隔的单词,则可以添加\s速记类,并匹配任何种类的空格,都可以使用Pattern.UNICODE_CHARACTER_CLASS标志来编译此正则表达式:

String regex = "(?U)[\\p{L}\\p{M}\\s]+";

请注意,此正则表达式允许以任何顺序输入变音符号,字母和空格。如果您需要更精确的正则表达式(例如,仅在基本字母后才允许变音符号),您可以考虑使用

String regex = "(?U)\\s*(?>\\p{L}\\p{M}*+)+(?:\\s+(?>\\p{L}\\p{M}*+)+)*\\s*";

在这里,(?>\\p{L}\\p{M}*+)+匹配一个或多个字母,每个字母后跟零个或多个变音符号,\s*匹配零个或多个空格,\s+匹配1个或多个空格。

\p{IsAlphabetic}[\p{L}\p{M}]

如果您检查source code,则\p{Alphabetic}检查Character.isAlphabetic(ch)是否为真。如果char属于以下任何类别,则为true:UPPERCASE_LETTERLOWERCASE_LETTERTITLECASE_LETTERMODIFIER_LETTEROTHER_LETTERLETTER_NUMBER < strong>或具有其他属性的其他财产。 is derived from Lu + Ll + Lt + Lm + Lo + Nl + Other_Alphabetic

虽然所有这些L子类都构成常规的L类,但请注意Other_Alphabetic还包括Letter number Nl类,并且比\p{M}类包含更多的字符,请参见this reference(尽管它是德语,但是类别和字符名称是英语)。

因此, \p{IsAlphabetic}[\p{L}\p{M}] 更为广泛,您应该根据要支持的语言做出正确的决定。

答案 1 :(得分:1)

我发现的唯一解决方案是使用\p{IsAlphabetic}

  

\ p {Alpha}一个字母字符:\ p {IsAlphabetic}

boolean isMatch = name.matches("[ \\p{IsAlphabetic}]+")) 

https://regex101.com/中的demo站点中不起作用

答案 2 :(得分:1)

搜索该字符以查找语言。好像是泰国人。泰语Unicode字符范围是:0E00 to 0E7F

使用Unicode字符时,可以使用\u。因此,正则表达式应如下所示:

[\u0E00-\u0E7F]

在此REGEX test中与您的角色匹配的人。

如果您想匹配任何语言,请使用此:

[\p{L}]

REGEX test中的哪个与您的示例字符匹配。

答案 3 :(得分:1)

那里有两个字符。第一个是字母,第二个是非字母标记。

String name = "\u0e2d";
boolean isMatch = name.matches("[\\p{L}]+"); // true

可以,但是

String name = "\u0e2d\u0e31";
boolean isMatch = name.matches("[\\p{L}]+"); // false

并不是因为ัU+E31是非间距标记[NSM],而不是字母。

答案 4 :(得分:1)

尝试包括更多类别:

canvas { border : 1px solid black; }
body { margin :0; }

请注意,最好不要验证名称。如果输入错误,人们就无法真正抱怨,但是您的系统没有抓住它。但是,如果某人无法输入自己的姓名,那就更成问题了。如果您确实坚持添加验证,请 please 使其可重写:应该具有每种方法的优点而没有缺点。