一个设计良好的系统不一定需要防止任何特殊字符在用户名中出现。
尽管如此,下划线之所以通常被接受,是因为它通常被视为“单词”字符,与字母和数字一样。在正则表达式中,它通常是唯一被赋予这种特殊性质的字符。即使在大多数操作系统的基本级别上也是如此(在单词中键入下划线并双击字母,选择将扩展到下划线之后。现在尝试使用破折号进行相同的操作,很可能不会成功)。
是的: 为了避免需要转义特殊字符. 懒惰的程序员会将用户输入的内容直接放入代码中,这就导致了注入攻击。
即使没有恶意使用,允许用户输入与其他地方冲突的字符可能会带来更多不必要的麻烦。例如,如果你决定为每个用户创建一个文件系统目录来存储他们的上传文件,那么用户名必须符合该操作系统上的目录命名规则(例如,在Windows上不能包含 \ / : *?"<>|
字符)。
一旦你避免了像目录命名这样的冲突,并去除了"';%
和 //
以避免注入攻击,你就已经删除了大部分标点符号,“为什么有人甚至需要在他们的用户名中使用标点符号呢?”
编写一个快速的正则表达式来验证用户名是否符合 [a-zA-Z0-9_]
比费尽心思弄清所有不可能导致冲突的标点符号或以某种方式映射它们到其他字符要容易得多。
然后,就像计算机中的许多事情一样,一旦足够多的人只使用字母、数字和下划线作为用户名,并且人们开始按照这个规范创建用户名,它就成为了事实上的标准并自我延续!
如果没有指定,我会使用这个:
(更新了正则表达式以修复@abney317提到的回溯问题backtracking)
^\w(?:\w|[.-](?=\w)){3,31}$
(原始正则表达式)
^\w(?:\w*(?:[.-]\w+)?)*(?<=^.{4,32})$
这需要长度为4,最大可达32个字符。它必须以字母数字字符开头,并且可以包含非连续的点和破折号。我之所以使用这个规则是因为它严格到足以与几乎任何东西集成 :)
有效:
test.tost
无效:
test..tost
限制用户名只能使用这些字符(甚至是它们的ASCII子集)可以防止像 这样的用户名被接受。通过不接受这些字符,您可以防止一系列看起来像其他用户名的用户名。
当可读性影响人们使用他们的母语作为用户名时,我不喜欢这种论点。
我建议您尝试使用包含http://msdn.microsoft.com/en-us/library/20bw873z.aspx#SupportedUnicodeGeneralCategories或http://msdn.microsoft.com/en-us/library/20bw873z.aspx#SupportedNamedBlocks的字符类。虽然我没有尝试过这个方法,但是
[\p{L}\p{N}\p{M}]
这可能值得尝试一下。
~-|this<>one|-~
这样的用户名很烦人)。也可能是因为它更少的工作量(下划线可以通过\w+
正则表达式匹配,而破折号和其他特殊字符不行),但我怀疑这不是主要原因。这取决于你的用户名是如何使用的。如果不知道上下文,就没有通用规则。
在大多数编程语言中,下划线通常被允许用于标识符,并且通常是唯一允许的“特殊”字符。
但许多Web登录仍然不接受任何特殊字符,限制为小写/大写字符和数字...
而其他则可以使用非常特殊的字符;-)
人们可能希望将他们的用户名写成这样,而不是像这样或者像这样。