Java-\pL[\x00-\x7F]&x2B;正则表达式无法使用String.match获取非英语字符
我需要验证保存在字符串中的名称,该名称可以是任何语言,并使用空格: 可以将属于“字母”类别的单个字符与\p{L}匹配 我尝试使用Java-\pL[\x00-\x7F]&x2B;正则表达式无法使用String.match获取非英语字符,java,regex,Java,Regex,我需要验证保存在字符串中的名称,该名称可以是任何语言,并使用空格: 可以将属于“字母”类别的单个字符与\p{L}匹配 我尝试使用String.matches,但它无法匹配非英语字符,例如,即使是1个字符 String name = "อั"; boolean isMatch = name.matches("[\\p{L}]+")); // return false 我尝试过使用括号/不使用括号,为多个字母添加+,但总是无法匹配非英语字符 使用String.matches与\p{L}匹配是否存在
String.matches
,但它无法匹配非英语字符,例如,即使是1个字符
String name = "อั";
boolean isMatch = name.matches("[\\p{L}]+")); // return false
我尝试过使用括号/不使用括号,为多个字母添加+
,但总是无法匹配非英语字符
使用String.matches
与\p{L}
匹配是否存在问题
我在使用中建议的[\\x00-\\x7F]+
时也失败了
我找到的唯一解决办法是使用 \p{Alpha}一个字母字符:\p{IsAlphabetic}
这在网站中不起作用,因为在Google上搜索该字符来查找该语言。好像是泰国人。泰语Unicode字符范围为: 使用unicode字符时,可以使用
\u
。因此,正则表达式应该如下所示:
[\u0E00-\u0E7F]
这与你的角色相匹配
如果要匹配任何语言,请使用以下命令:
[\p{L}]
这与您的示例字符相匹配。有两个字符。第一个是字母,第二个是非字母标记
String name = "\u0e2d";
boolean isMatch = name.matches("[\\p{L}]+"); // true
有效,但是
String name = "\u0e2d\u0e31";
boolean isMatch = name.matches("[\\p{L}]+"); // false
不是因为ั 是非间隔标记[NSM],不是字母。尝试包含更多类别:
[\p{L}\p{Mn}\p{Mc}\p{Nl}\p{Pc}\p{Pd}\p{Po}\p{Sk}]+
请注意,最好不要验证名称。如果输入错误,人们不会真正抱怨,但您的系统没有捕捉到。然而,如果有人无法输入自己的名字,问题就更大了。如果您坚持要添加验证,请将其设置为可重写的:这应该具有每种方法的优点而不存在缺点。您应该记住,Java正则表达式将字符串解析为Unicode代码单元的集合,而不是代码点
\p{L}
匹配BMP平面中的任何Unicode字母,但不匹配在其后面粘贴有变音符号的字母
由于您的输入可以包含字母和变音符号,您至少应该在字符类中同时使用\p{L}
和\p{M}
Unicode属性类:
String regex = "[\\p{L}\\p{M}]+";
如果输入字符串可以包含用空格分隔的单词,您可以添加\s
速记类,为了匹配任何类型的空格,您可以使用模式编译此正则表达式。UNICODE\u CHARACTER\u 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+
匹配一个或多个空格
\p{IsAlphabetic}
vs.[\p{L}\p{M}]
如果检查,\p{Alphabic}
检查字符.isAlphabetic(ch)
是否为真。如果字符属于以下任何类别,则为真:大写字母
,小写字母
,标题字母
,修饰字母
,其他字母
,字母号
,或者它具有其他字母的辅助属性。它Lu+Ll+Lt+Lm+Lo+Nl+其他字母
虽然所有这些L
子类构成了一般的L
类,但请注意Other_字母
也包括类,并且它包含的字符比\p{M}
类更多,请参见(虽然它是德语,但类别和字符名称是英语)
因此,
\p{IsAlphabetic}
比[\p{L}\p{M}]
更广泛,你应该根据你想要支持的语言做出正确的决定。你的名字只有一个字符?@CarlosHeuberger没有,但即使在单字符匹配中使用\pL,它仍然失败,我需要英语和非英语字符,不仅是泰语,而且感谢泰语参考。我会检查它,但它也来自用户输入,以及为什么/如何IsAlphabetic
在这种情况下工作?@user7294900。很抱歉我的错误。我现在看到一个变音符号ั 逻辑结论是,“[\\p{L}\\p{M}]+”
将正确匹配该字符串。我必须验证用户输入,您能解释类别吗?你能添加参考链接/demo吗?@user7294900我用过,用来查找类别。谢谢你的回复,它可以工作,但它添加了很多问题,例如为什么添加\p{Pd}匹配任何类型的连字符或破折号\p{Po}匹配任何类型的非破折号、括号的标点字符,quote还是connector?@user7294900如果你问为什么Unicode标准是这样设计的,我没有任何答案。我也认为这是一个混乱。如果你有什么问题,请你澄清一下你的问题好吗?谢谢,为什么比\p{IsAlphabetic}
?@user7294900更好?我添加了更多细节。
String regex = "(?U)[\\p{L}\\p{M}\\s]+";
String regex = "(?U)\\s*(?>\\p{L}\\p{M}*+)+(?:\\s+(?>\\p{L}\\p{M}*+)+)*\\s*";