Java 用于验证本地化字符串中的字母和数字的正则表达式

Java 用于验证本地化字符串中的字母和数字的正则表达式,java,regex,unicode,localization,Java,Regex,Unicode,Localization,我有一个本地化的输入字段。我需要使用正则表达式添加一个验证,它必须只使用字母和数字。如果我只使用英语,我本可以使用[a-z0-9] 到目前为止,我正在使用方法Character.isleterordigit(name.charAt(I))(是的,我正在遍历每个字符)过滤掉各种语言中的字母表 有没有更好的方法?是否有任何regex或其他库可用于此目的 boolean foundMatch = name.matches("[\\p{L}\\p{Nd}]*"); 应该有用 [\p{L}\p{Nd}]

我有一个本地化的输入字段。我需要使用正则表达式添加一个验证,它必须只使用字母和数字。如果我只使用英语,我本可以使用
[a-z0-9]

到目前为止,我正在使用方法
Character.isleterordigit(name.charAt(I))
(是的,我正在遍历每个字符)过滤掉各种语言中的字母表

有没有更好的方法?是否有任何regex或其他库可用于此目的

boolean foundMatch = name.matches("[\\p{L}\\p{Nd}]*");
应该有用


[\p{L}\p{Nd}]
匹配Unicode字母或数字字符。regex
.matches()
方法确保整个字符串与模式匹配。

自Java 7以来,您可以使用
模式。UNICODE\u CHARACTER\u CLASS

String s = "Müller";

Pattern p = Pattern.compile("^\\w+$", Pattern.UNICODE_CHARACTER_CLASS);
Matcher m = p.matcher(s);
if (m.find()) {
    System.out.println(m.group());
} else {
    System.out.println("not found");
}
如果没有该选项,它将无法识别单词“Müller”,而是使用
Pattern.UNICODE\u CHARACTER\u CLASS

启用预定义字符类和POSIX字符类的Unicode版本

您还可以看看Java7

这里是对Unicode脚本、属性和块的概述

关于Java中正则表达式的注意事项,包括更新的Java 7中发生的变化(当然是Java 8中的变化)

有些人在遇到问题时会想:“我知道,我会用 现在他们有两个问题

--

我开玩笑地说,但是像您这样迭代字符串将具有至少与任何正则表达式一样好的运行时性能-正则表达式无法更快地完成您想要的事情;而且您一开始就没有编译模式的开销

只要:

  • 验证不需要做任何其他类似regex的事情(问题中没有提到)
  • 代码在字符串中循环的意图是明确的(如果没有,重构直到它被激活)

那么为什么要用正则表达式替换它呢?

那么你想处理除英语以外的其他语言,对吗?根据帖子的说法,
\w
在unicode字符的perl正则表达式中也有效,我不知道在java正则表达式中是否如此。@beerbajay这不再是完全正确的,它仍然是标准,但是
Pattern.UNICODE\u CHARACTER\u CLASS
启用预定义字符类和POSIX字符类的UNICODE版本。@请注意,在Java中使用
charAt
总是错误的。您应该调用
codepoint
,并相应地调整
i
。我必须指出,您使用了“字母表”一词。我相信,你真正的意思是剧本。顺便说一句,请注意,答案中提到的正则表达式包含所有数字,包括。您可能还想了解。可以找到其他可能的unicode类别(例如
L
N
),您不需要为7个主要类别使用大括号。您可能还喜欢
\pM
,因此
[\pL\pM\pN]
。请注意,这已经是一个比
\p{alphastic}
更广泛的定义,因为它包括所有标记,而不仅仅是其中的一些。这使它更接近用于程序标识符的
\p{word}
属性,它是
[\p{alpha}\p{gc=Mark}\p{gc=Digit}\p{gc=Pc}]
,其中
\p{alpha}
很复杂,但基本上只选择了几个标记。@TimPietzcker等等:你的布尔测试是错误的。所有可能的字符串都匹配任何内容的零次或多次重复。我想你不想要那个明星。另外,正如其他地方所评论的,尽管它可能是您想要的,
\pN
不仅仅是数字
\p{Nd}
只是十进制数字,没有罗马数字、粗俗分数、子字符和上标字符等。只需调用
\pN
任何数字,而不是任何数字,您就对了。@tchrist:
matches()
方法要求正则表达式匹配整个输入字符串,而不仅仅是子字符串。因此,它仅在整个字符串由字母/数字组成时匹配(或者为空,可以说也符合该定义)。关于
\p{Nd]}
的观点很好。当然,这也会匹配下划线和其他连接标点。@TimPietzcker这是真的,如果这很重要的话,那么你的答案将是OP(+1)的更好选择。@TimPietzcker在
UNICODE\u CHARACTER\u类下,所谓的POSIX类也匹配per;也就是说,
\p{alpha}
成为-当且仅当在
模式
编译标志下编译时-完全等于Unicode
Alphaic=True
属性,该属性本身有点复杂,但非常有用,并且不包括连接器标点。对不起,这句话太多了。:)只是为了补充这个答案,Unicode字符类可以通过嵌入表达式?U启用,如中所述。通过测量来支持这一说法将是很有趣的。+1您可以同意或不同意,这确实是一个有趣的链接@蒂姆:你甚至不需要测量。除非您使用的是量子计算,否则您无法验证字符列表(也称为字符串)中的所有字符都是字母或数字,而不访问每个字符,并在找到一个不是字母或数字的字符后立即停止。因为这是自定义代码所做的,所以这是尽可能少的工作量。正则表达式不是魔法。正则表达式比手工编码更容易正确。例如,您是否记得使用
codePointAt
而不是OP使用的错误
charAt
?regex会帮你处理的。手工编写的代码可以像正则表达式一样紧凑,但通常不是。这取决于你想花多少时间来制作它,而不是做正则表达式库的人花多少时间来制作它。正则表达式可以替换复杂、容易出错的代码页。始终使用注册表