【问题标题】:Regex that expresses "at least one non-digit"表示“至少一个非数字”的正则表达式
【发布时间】:2010-01-24 04:08:52
【问题描述】:

我想根据这个架构验证用户名:

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

这个正则表达式满足上面的1和2,但是我不知道怎么满足3:

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

(我正在使用 Ruby,如果相关的话)

【问题讨论】:

    标签: ruby regex


    【解决方案1】:

    效率不高,但简单:

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

    前瞻只是意味着:“接下来的不是一串一直持续到最后的数字”。

    【讨论】:

    • 巧妙的技巧,它在非 ruby​​ 正则表达式实现中可用吗?
    • +1 不错。我通常避免使用前瞻,因为我没有很好地掌握它们,但这是如何使用它们的一个很好的说明。
    • @Mark:不是全部,而是最多。我知道 Python、PHP、Perl 和 Javascript 都支持它。
    【解决方案2】:

    如果您可以进行两次传递,则更简单、更快的第二次传递正则表达式是:

    /[^\d]/
    

    这只是匹配任何不是数字的东西,它只需要匹配一个并且它会提前终止。您实际上不需要在这里严格,因为第一遍已经拒绝了不允许的字符。

    【讨论】:

      【解决方案3】:

      不理想,但很简单:使用正则表达式 /^.*[a-zA-Z_\-].*$/ 进行第二次传递

      只要确保两者都通过,你会没事的。

      【讨论】:

      • 如果您运行第二个过滤器,/\D/ 也会做同样的事情。无需从头到尾匹配。
      • 第二遍可以是[-a-z_](我假设你正在做一个不区分大小写的匹配;如果不是,那么[-A-Za-z_],当然。不用担心开始,结束或其他任何东西——如果它通过了第一个,只要确保任何地方都有一个字母、下划线或连字符。
      • 谢谢,我不确定 Ruby,但 Java 仅在整个字符串匹配时才报告匹配。我假设 \D 不是数字?
      • @David:是的,非数字。至于匹配,大多数引擎(包括Java)都提供了match() 和search()/find() 方法。前者尝试匹配整个字符串,而后者尝试在任意点匹配。
      • 这就是我喜欢 SO 的原因,我每天都能学到新的有用的东西。
      【解决方案4】:

      我会使用验证所需的正则表达式,然后是:

      passwd.to_i.to_s.length != passwd.length
      

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

      【讨论】:

        【解决方案5】:

        还有另一种方式,尽管它的性能可能不如 Max 的:

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

        【讨论】:

          猜你喜欢
          • 2013-06-24
          • 1970-01-01
          • 2013-05-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-24
          • 1970-01-01
          相关资源
          最近更新 更多