Java Regex - 允许使用所有常规 Unicode 字符作为名称,但不允许使用晦涩的变体

Jan*_*ing 7 java regex

在java(v11)中,我希望允许任何语言中的所有字符来选择用户名,例如ASCII、拉丁语、希腊语、中文等。

\n\n

我们尝试了该模式\\p{IsAlphabetic}

\n\n

但在这种模式下,像“”这样的名称是允许的。我不想让人们用这样的 unicode 字符来设计他们的名字。我希望他输入“Chris”而不是“”

\n\n

应该允许将自己命名为“\xe5\xb0\xa4\xe9\x9b\xa8\xe6\xba\xaa”、“Linus”或“G\xc3\xb6del”。

\n\n

如何实现正确的正则表达式不允许名称中出现奇怪的样式?

\n

Boh*_*ian 1

挑战在于它由代理对组成,正则表达式引擎将其解释为代码点,而不是字符。

\n

解决方案是使用 匹配任何字母\\p{L},但排除上面的高代理项的代码点:

\n
"[\\\\p{L}&&[^\\\\x{0d000}-\\\\x{10ffff}]]+"\n
Run Code Online (Sandbox Code Playgroud)\n
\n

尝试排除 unicode 字符

\n
"[\\\\p{L}&&[^\\ud000-\\uffff]]+" // doesn't work\n
Run Code Online (Sandbox Code Playgroud)\n

不起作用,因为代理对被合并到单个代码点中。

\n
\n

测试代码:

\n
String[] names = {"\xe5\xb0\xa4\xe9\x9b\xa8\xe6\xba\xaa", "Linus", "G\xc3\xb6del", "\\uD835\\uDD6E\\uD835\\uDD8D\\uD835\\uDD97\\uD835\\uDD8E\\uD835\\uDD98"};\n\nfor (String name : names) {\n    System.out.println(name + ": " + name.matches("[\\\\p{L}&&[^\\\\x{0d000}-\\\\x{10ffff}]]+"));\n}\n
Run Code Online (Sandbox Code Playgroud)\n

输出:

\n
\xe5\xb0\xa4\xe9\x9b\xa8\xe6\xba\xaa: true\nLinus: true\nG\xc3\xb6del: true\n: false\n
Run Code Online (Sandbox Code Playgroud)\n