使用正则表达式验证字符串是否符合URL安全要求

16

我有一个网站,用户可以选择用户名。目前,他们可以输入几乎任何字符,包括@ !#等特殊字符。

我知道我可以使用正则表达式,这可能是我要选择的方式。

我将使用否定集合,在这里假设这是正确的工具:

[^@!#]

那么,我如何知道所有非法字符并将它们放入该集合中呢?我可以手动添加一些明显的(比如! @#$%^& *()),但是否有一种简单的方法可以不用手动添加每一个字符呢?

我知道很多网站只允许包含字母、数字、破折号或下划线的字符串。像这样的东西对我很有用。

任何帮助都将不胜感激。

谢谢S.O.!


2
如果你知道想要包含什么(字母数字+连字符+下划线),为什么要使用否定集合? - univerio
4个回答

31

不要使用否定表达式,只在字符类中放入您想要允许的内容。

^[a-zA-Z0-9_-]*$

解释:

^                 # the beginning of the string
 [a-zA-Z0-9_-]*   #  any character of: 'a' to 'z', 'A' to 'Z', 
                  #  '0' to '9', '_', '-' (0 or more times)
$                 # before an optional \n, and the end of the string

感谢正则表达式。对于这种情况,只编写一个包容性集合确实更有意义! :) - Isaiah Lee
1
@hwnd - 看起来不错,但我想知道为什么“/”字符在URL中也不被视为安全字符 - 在路径中似乎是基本的。 - Reinsbrain
@Reinsbrain 这个问题说明了正则表达式正在检查一个用户名。我猜测这个用户名被用作URL的一部分,例如www.example.com/[username]/settings。当检查完整有效的URL时,允许'/'是有意义的,但在检查字符串是否可以用作URL的一部分时则不然。要理解为什么,请想象一个以'/'开头或结尾的用户名的用户。 - Gino
3
RFC-3986规定 ALPHA DIGIT "-" / "." / "_" / "~",因此为了完整起见,应该写成:^[a-zA-Z0-9._~-]*$ - Ben Golding
1
补充一下这个很好的答案(和评论),\w(单词字符)是[a-zA-Z0-9_]的简写,所以我现在使用:^[\w.~-]*$。感谢大家的帮助! - Joel Balmer

3

谢谢。我已经收藏了那个链接,以备将来之需。 - Isaiah Lee

2

使用包含所有字符的字符集的原因之一是,由于存在各种Unicode变体,限制不良字符非常困难。例如ß、ñ、oœ、æ等字符可能会让您感到头痛。如果您将用户名限制为您提供的字母子集,您可以轻松地剔除其中任何其他不想要的内容。


这非常有道理。谢谢你的解释 :) - Isaiah Lee

2

这个问题的所有答案似乎都假设使用英语语言。为了允许Unicode字符(以便人们可以在其本地语言中拥有URL /用户名),最好使用一个保留/不安全字符的黑名单,而不是字符的白名单。

下面是一个正则表达式,用于匹配URL中通常不安全的字符:

([&$\+,:;=\?@#\s<>\[\]\{\}[\/]|\\\^%])+

测试正则表达式的链接

(基于此答案中提到的不安全字符列表)


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