我有一个已经进行了本地化的输入框。 我需要使用正则表达式添加验证,以确保它只接受字母和数字。 如果我只使用英语,我可以使用[a-z0-9]
。
目前,我正在使用Character.isLetterOrDigit(name.charAt(i))
方法(是的,我正在迭代每个字符)来过滤出各种语言中存在的字母。
是否有更好的方法? 是否有任何正则表达式或其他库可用于此?
我有一个已经进行了本地化的输入框。 我需要使用正则表达式添加验证,以确保它只接受字母和数字。 如果我只使用英语,我可以使用[a-z0-9]
。
目前,我正在使用Character.isLetterOrDigit(name.charAt(i))
方法(是的,我正在迭代每个字符)来过滤出各种语言中存在的字母。
是否有更好的方法? 是否有任何正则表达式或其他库可用于此?
自Java 7以来,您可以使用Pattern.UNICODE_CHARACTER_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_CHARACTER_CLASS
启用预定义字符类和POSIX字符类的Unicode版本。
在Java 7中此处可以查看更多详细信息
您还可以在Java 7中此处查看更多有关Unicode的信息
在此处查看tchrist所提供的一份著名答案,其中包括Java正则表达式的注意事项及Java 7中已更改的内容(或者将在Java 8中更改)
UNICODE_CHARACTER_CLASS
下,所谓的POSIX类也会匹配UTS#18 Annex C中的内容;也就是说,如果且仅当在Pattern
编译标志下编译时,\p{alpha}
将完全等同于Unicode Alphabetic=True
属性,该属性本身有些复杂但非常有用,并且不包括连接符标点符号。抱歉句子有点长。 :) - tchristboolean foundMatch = name.matches("[\\p{L}\\p{Nd}]*");
应该可以工作。
[\p{L}\p{Nd}]
匹配一个Unicode字母或数字。正则表达式的 .matches()
方法确保整个字符串与模式匹配。
\pM
,因此使用[\pL\pM\pN]
。请注意,这已经是比\p{Alphabetic}
更广泛的定义,因为它包括所有标记,而不仅仅是其中一些。这使其更接近用于程序标识符的\p{word}
属性,根据UTS#18 Annec C,它是[\p{alpha}\p{gc=Mark}\p{gc=Digit}\p{gc=Pc}]
,其中\p{alpha}
很复杂,但基本上只选择了一些标记。 - tchrist\pN
不仅仅代表数字; \p{Nd}
只是没有罗马数字、分数、上下标等的十进制数字。只需将 \pN
称为任何数值,而不是任何数字,你就会明白了。 - tchristmatches()
方法要求正则表达式匹配整个输入字符串,而不仅仅是子字符串。因此,它只有在整个字符串由字母/数字组成(或为空,这也可以算作符合该定义)时才匹配。\p{Nd}
的观点很好。 - Tim PietzckercodePointAt
而不是 OP 所使用的错误的 charAt
?而正则表达式已经替你处理了这个问题。手写代码可能与正则表达式一样紧凑,但通常并不如此。这取决于你愿意花多少时间来精心编写它,以及那个编写正则表达式库的人花了多少时间来制作它。一个正则表达式可以替换掉数页复杂、容易出错的代码。始终先使用正则表达式,然后仅在性能测试证明需要时才进行优化。程序员的时间胜出。 - tchrist
\w
在perl的正则表达式中也适用于Unicode字符,我不知道Java的正则表达式是否也是如此。 - user1227804Pattern.UNICODE_CHARACTER_CLASS
启用了预定义字符类和POSIX字符类的Unicode版本。 - stemacharAt
总是错误的。你应该调用codePointAt
,并相应地调整你的i
。 - tchrist