繁体   English   中英

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

[英]Java - \pL [\x00-\x7F]+ regex fails to get non English characters using String.match

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

您可以将属于“字母”类别的单个字符与\\ p {L}匹配

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

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

我尝试使用/不使用括号,为多个字母添加+ ,但它总是无法匹配非英语字符

使用带有\\p{L} String.matches是否存在问题?

我也失败了在Pattern中使用[\\\\x00-\\\\x7F]+建议

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

您应该记住,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}]

如果检查源代码\\p{Alphabetic}检查Character.isAlphabetic(ch)是否为true。 如果char属于以下任何类,则为true: UPPERCASE_LETTERLOWERCASE_LETTERTITLECASE_LETTERMODIFIER_LETTEROTHER_LETTERLETTER_NUMBER 或者它具有贡献属性Other_Alphabetic 源自 Lu + Ll + Lt + Lm + Lo + Nl + Other_Alphabetic

虽然所有这些L子类形成了一般的L类,但请注意Other_Alphabetic还包括字母编号 Nl类,并且它包含的字符数比\\p{M}类多,请参阅此参考 (尽管它是德语,类别和字符名称是用英语讲)。

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

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

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

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

哪个在网站中不起作用,如https://regex101.com/演示中

用Google搜索该字符以找到该语言。 似乎是泰国人。 泰语Unicode字符范围是: 0E00到0E7F

当您使用unicode字符时,您可以使用\\u\u003c/code> 。 所以,正则表达式应该是这样的:

[\u0E00-\u0E7F]

这个REGEX测试与你的角色匹配。

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

[\p{L}]

这个REGEX测试与您的示例字符匹配。

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

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

有效,但是

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

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

尝试包含更多类别:

[\p{L}\p{Mn}\p{Mc}\p{Nl}\p{Pc}\p{Pd}\p{Po}\p{Sk}]+

请注意,最好不要验证名称。 如果他们输入错误但人们没有抓住它,人们就不会抱怨。 但是,如果有人无法输入他们的名字,那就更成问题了。 如果你坚持要添加验证, 请将其覆盖:这应该具有每种方法的优点而没有它们的缺点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM