javax.validation.constraints的@Pattern可以正确处理非ASCII Unicode字符吗?

3
我需要验证输入的域名。我使用javax.validation和hibernate-validator:6.0.9.Final来实现此功能。
我的正则表达式是((([\p{L}0-9])+(-?[\p{L}0-9])*)\.)*[\p{L}0-9](-?[\p{L}0-9])+\.\p{L}{2,}。另外,我尝试在@Pattern注释中使用标志(?U)而不是\p{L},如\p{Alpha}。它在IntelliJ IDEA等工具中可以工作。所以我将其放入@Pattern注释中。从IDEA运行的测试可以正常工作。但是从Gradle运行的测试无法识别非ASCII字符的域名,例如,西里尔字母域名“мой-домен.рф”会导致ConstraintViolationException异常。
在java.util.regex.Pattern类的javadoc中,他们说内嵌的标志表达式(?U)仅适用于US-ASCII符号:

当指定此标志时,则(仅限US-ASCII)预定义字符类和POSIX字符类符合Unicode技术标准#18:Unicode正则表达式附录C:兼容性属性。

因此,我可以同意\p{Alpha}可能无法处理非ASCII字母。但是为什么\p{L}不起作用?
谁错了:hibernate-validator只与US-ASCII一起使用,还是IDEA可以处理所有Unicode字母(包括非ASCII字符)?为什么从IDEA运行的测试和从Gradle运行的测试在相同的JVM中表现不同?是否设置了不同的命令行参数?我在IDEA和Gradle脚本中都将文件编码设置为UTF-8。

你确定你参考了适当的文档吗?在Java正则表达式中,\p{L}不需要UNICODE_CHARACTER_CLASS标志来匹配Unicode字母,它默认就可以。 - Wiktor Stribiżew
我只在 \p{Alpha} 中使用 (?U)。 - Donz
2个回答

1

我的错误在于在Gradle脚本中设置UTF-8编码有误。

compileJava.options.encoding = 'UTF-8'

在 build.gradle 中。
systemProp.file.encoding=utf-8 

在gradle.properties中实际上不起作用。只有

标签。

tasks.withType(JavaCompile) {
    options.encoding = "UTF-8"
}

在build.gradle中工作。通过这个设置,测试在两个环境中都是正确的。

0

我使用了一个简化的模式来展示Unicode支持的工作。

    Pattern pattern = Pattern.compile("(?U)[-.\\p{L}]+");
    String s = "321";
    System.out.println(s + " -> " + pattern.matcher(s).matches());
    s = "mia-domajno.rf";
    System.out.println(s + " -> " + pattern.matcher(s).matches());
    s = "мой-домен.рф";
    System.out.println(s + " -> " + pattern.matcher(s).matches());

将产生(如预期):

321 -> false
mia-domajno.rf -> true
мой-домен.рф -> true

所以罪魁祸首是正则表达式的组成。目前我还没有清晰的头脑。

谢谢。我已经找到真正的罪魁祸首 - 是我自己 :) 我在Gradle中错误地设置了编译器的编码。 - Donz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接