javax.validation.constraints的@Pattern是否适用于非ASCII Unicode正确?

时间:2018-04-18 16:07:20

标签: java regex validation unicode

我需要验证输入的域名。我使用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,}我还尝试\p{Alpha}使用标记(?U)而不是\p{L}。例如,它适用于IntelliJ IDEA。所以我把它放到@Pattern注释中。 IDEA的测试运行正常。但是从Gradle运行的测试不起作用 - 验证器无法识别具有非ACII字符的域名,例如,西里尔字段“мой-домен.рф”会导致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字母?为什么从IDEA运行的测试运行和从Gradle运行的测试运行不同于相同的JVM?设置了一些不同的命令行参数?我在IDEA和Gradle脚本中都将UTF-8设置为文件编码。

2 个答案:

答案 0 :(得分: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

因此,罪魁祸首是正则表达式的组成。对此我目前没有明确的头脑。

答案 1 :(得分:0)

我的错误是在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中的

有效。使用此设置,测试在两种环境中都是正确的。