Regex UTF-8编码的多语言输入验证

Regex UTF-8编码的多语言输入验证,regex,validation,unicode,utf-8,internationalization,Regex,Validation,Unicode,Utf 8,Internationalization,为了检查用户输入的英文名称是否有效,我通常会将输入与正则表达式(如[a-Za-z])进行匹配。但是,如果utf8编码需要多语言(如中文、日文等)支持,我该怎么做呢?考虑一下您是否真的需要验证用户名。也许你应该让用户随意称呼自己 您当然不应该使用[A-Za-z],因为有些人的名字带有撇号或连字符。阻止某人使用他们的真名可能是相当侮辱性的,因为它没有遵循你关于名字应该是什么样子的任意规则。在PHP中,我使用了这个讨厌的黑客: setlocale(LC_ALL, 'de_DE'); preg_ma

为了检查用户输入的英文名称是否有效,我通常会将输入与正则表达式(如[a-Za-z])进行匹配。但是,如果utf8编码需要多语言(如中文、日文等)支持,我该怎么做呢?

考虑一下您是否真的需要验证用户名。也许你应该让用户随意称呼自己


您当然不应该使用
[A-Za-z]
,因为有些人的名字带有撇号或连字符。阻止某人使用他们的真名可能是相当侮辱性的,因为它没有遵循你关于名字应该是什么样子的任意规则。

在PHP中,我使用了这个讨厌的黑客:

 setlocale(LC_ALL, 'de_DE');
 preg_match('/^[[:alpha:]]+$/', $name);
这包括“Umlauts”(即“ä”、“ö”等)加上重音元音(è、í等)。
但是它无法验证西里尔文(俄罗斯、保加利亚等)或中文字符…

如果您的语言不直接支持正确的字母属性,您可以使用
[\pL\pM\p{Nl}]
非常简洁地近似Unicode派生属性

不要使用Java的
\p{Alpha}
,因为

但是你会注意到你没有考虑到破折号(
\p{Pd}
或破折号标点符号的作用,但这并不包括大多数连字符!)、撇号(通常但不总是U+27、U+2BC、U+2019或U+FF07中的一个)、逗号或句号/句号

为了以防万一,您可能最好包括
\p{Pc}
connectorputuation

如果您有Unicode派生属性
\p{Diacritic}
,那么您也应该使用它,因为它包括加泰罗尼亚语中成对L所需的中间点以及人们有时使用的非组合形式的变音符号

但是你会发现人们在他们的名字中使用序数的方式是
\p{Nl}
(字母数)无法适应的,所以你把
\p{Nd}
(小数)甚至所有的
\pN
(数字)混合在一起

然后,您意识到亚洲名称通常需要使用ZWJ或ZWNJ才能在其脚本中正确书写,因此您必须将U+200D和U+200C添加到组合中,这两个字符都是
\p{Cf}
(格式)字符,实际上也是JoinControl字符


当你对不断出现的各种各样的外来字符进行处理时——或者当你认为你已经完成了时——你几乎可以肯定地得出结论,如果你按照建议允许他们使用他们想要的任何Unicode字符作为他们的名字,你会做得更好。是的,你会看到一些小丑加入诸如“你”之类的内容⅂ əɯɐuʇƨɹᴉℲ”, 但这只是一个领域,你不能以任何合理的方式排除愚蠢的名称。

你使用什么语言/正则表达式实现?理想情况下支持所有语言,这是可能的吗?我认为Gumbo的意思是“你在使用什么编程语言?”阅读。我不知道我更喜欢这个答案是什么:它确实回答了这个问题,它可能会教授很多关于unicode正则表达式的知识,或者它简洁地说明了为什么尝试验证实名是个坏主意。