正则表达式表示“至少有一个非数字字符”

9

我希望根据以下模式验证用户名:

  1. 允许字符:字母、数字、连字符、下划线
  2. 第一个字符必须是字母或数字
  3. 用户名不能全部由数字组成

这个正则表达式满足了1和2的要求,但我无法想出如何满足第3个要求:

/^[a-zA-Z\d][\w\-]+$/

(如果相关的话)我正在使用Ruby。
5个回答

11

虽然不太高效,但是非常简单:

/^(?!\d+$)[a-zA-Z\d][\w\-]+$/

这个前瞻正则表达式的意思是:"后面不是一连串数字直到最后"。


这个巧妙的技巧,在非 Ruby 正则表达式实现中是否可用? - Mark Elliot
+1 很好。我通常会避免使用前瞻(lookahead), 因为我对它们的理解不太透彻,但这个示例很好地展示了如何使用它们。 - Decent Dabbler
@Mark:不是全部,但大多数编程语言都支持。我知道支持它的有Python、PHP、Perl和Javascript。 - Max Shawabkeh

2

如果您可以使用两个正则表达式,第二次更简单和更快的匹配方法是:

/[^\d]/

这只匹配任何不是数字的内容,它仅需要匹配一次并尽早终止。在这里您不需要严格要求,因为第一次匹配已经拒绝了不允许的字符。


1

虽然不是最理想的方法,但很简单:使用正则表达式/^.*[a-zA-Z_\-].*$/进行第二次匹配。

只要确保两次匹配都通过,就没问题了。


2
如果您运行第二个过滤器,则“/\D/”同样适用。没有必要从开头到结尾匹配。 - Max Shawabkeh
第二次可以只是[-a-z_](我假设您正在进行不区分大小写的匹配;如果不是,则当然是[-A-Za-z_]。不需要担心开头、结尾或其他任何事情——如果它通过了第一个,只需确保有字母、下划线或连字符即可。 - Jay
谢谢,我不确定Ruby,但Java只有在整个字符串匹配时才报告匹配。我假设\D不是数字? - David Kanarek
@David:是的,非数字字符。至于匹配,大多数引擎(包括Java)都提供了match()search()/find()方法。前者尝试匹配整个字符串,而后者则尝试在任何位置匹配。 - Max Shawabkeh
这就是为什么我喜欢 Stack Overflow,我每天都能学到新的有用知识。 - David Kanarek
实际上,如果我们谈论两个步骤,第一步应该是/^\d+$/。如果用户名全是数字,它将否定需要第二步。另外,/^(\d|-)$/可能更好。 - Elizabeth Buckwalter

0
我会使用你需要用于验证的正则表达式,然后类似这样:
passwd.to_i.to_s.length != passwd.length

在通过主要验证后,验证passwd不是数字字符串。


0

另一种方法,虽然可能不如Max的表现好:

/^[a-z0-9][-\w]*[-_a-z][-\w]*$/i

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