这个正则表达式有什么问题,如何改进?

时间:2012-12-25 20:50:39

标签: php regex

我正在使用以下正则表达式代码:

^[a-z0-9_-]{3,15}$^

我正在使用它进行用户名验证,我希望它与字母数字字符匹配,-_和句点。

发生以下奇怪的事情:

它与此不匹配:

bla.b

但它匹配这一个:

bla.blabla

我如何更改它,以便它们兼容?我仍然希望能够自由地改变最小和最大字符。 (顺便说一句。关于这个正则表达式可能有更多错误的东西。这是我偶然发现的那个)

更新:我应该提一下,我在CakePHP验证中使用它,这给了我一个错误:

^[a-z0-9_.-]{3,15}$

这是错误:

Warning (2): preg_match() [function.preg-match]: No ending delimiter '^' found

3 个答案:

答案 0 :(得分:8)

你犯了一个小错误,忘了把^放在开头。选择不同的分隔符可能会使其更加明显:

^[a-z0-9_-]{3,15}$^    // your non-working version
^                 ^

/^[a-z0-9_-]{3,15}$/  // using / as delimiters instead, setting the beginning
 ^

记住:

  • ^ - 标志着主题的开始
  • $ - 标志着主题的结束

两者都是模式的一部分。分隔符用于将模式与修饰符分开(此处不使用任何修饰符)。

如果有帮助,您也可以使用\A\Z来表示开头和结尾。

现在也要匹配点,将其添加到角色类:

/^[a-z0-9_.-]{3,15}$/
          ^

答案 1 :(得分:5)

^[a-z0-9_-]{3,15}$^

应该是:

^[a-z0-9_-]{3,15}$

^表示字符串的开头,$表示字符串的结尾。

答案 2 :(得分:1)

这应该这样做:

/^[a-z0-9_\.\-]{3,15}$/

如果您想匹配用户名,那么您可能不希望它以点开头或结尾。在这种情况下,您可以使用:

/^(?<!\.)[a-z0-9_\.\-]{3,15}(?!\.)$/

这就是正则表达式崩溃的原因:

  1. ^表示“字符串的开头”
  2. (?<!\.)确保用户名不能以点开头
  3. [a-z0-9\._-]{3,15}表示3到15个字母数字字符,点,下划线和连字符
  4. (?!\.)确保用户名不能以点结尾
  5. $表示“字符串结尾”
  6. 如果你允许使用大写字符,那么你可以稍微缩短正则表达式:

    /^(?<!\.)[\w\.\-]{3,15}(?!\.)$/
    

    \w[a-zA-Z0-9_]的缩写,也称为字符

    另一种确保用户名不以点开头或结尾的方法是连续使用三个[],如下所示:

    /^[\w\-][\w\.\-]{1,13}[\w\-]$/
    

    如果您需要在Javascript中匹配某些东西,我相信它不支持lookbehind和lookahead,这可能很有用。