【问题标题】:Regex for a password field validation [duplicate]用于密码字段验证的正则表达式 [重复]
【发布时间】:2013-04-09 11:05:41
【问题描述】:

如果这段代码很糟糕,我很抱歉,因为我在不到一个月前刚开始使用 php 时,正在阅读一本书并为我的学校项目修改它。

我正在尝试理解此验证的含义,但似乎无法完全理解它,因为我是 php 新手。

代码:

if (preg_match ('/^(\w*(?=\w*\d)(?=\w*[a-z])(?=\w*[A-Z])\w*){6,20}$/', $_POST['pass']) ) {

        //$p = mysqli_real_escape_string ($dbc, $_POST['pass']);
        $p = $_POST['pass'];
        $sticky_password = $p;

        } else {
        $error['pass'] = 'Please enter a valid password!';
        }

任何帮助将不胜感激!谢谢!

非常感谢.. :)

【问题讨论】:

  • 我的任何密码都会失败,它们总是包含特殊字符,并且总是超过 20 多个字符。不要强迫我在你的网站上设置垃圾密码。
  • 你可以用/^\w{2,20}$/替换/^[a-z\d_]{2,20}$/i
  • 为什么使用正则表达式来验证用户名或密码?你所做的只是给用户带来不便。如果您试图防止黑客入侵,那么有更好的技术。
  • @GitKidd:书中的大多数代码只是示例性的,并不是为了以后真正使用而复制和粘贴。保重。

标签: php html regex


【解决方案1】:

我们有以下正则表达式: /^(\w*(?=\w*\d)(?=\w*[a-z])(?=\w*[A-Z])\w*){6,20}$/

  1. 第一个和最后一个/ 是分隔符。

  2. ^ -> 开始,$ -> 结束

    这意味着如果输入是 abc 并且您的正则表达式是 /^bc$/,它将不会被匹配,因为 bc 不在开头。

  3. 现在我们有(\w*(?=\w*\d)(?=\w*[a-z])(?=\w*[A-Z])\w*){6,20}

    {6,20}是量词部分,表示6到20次。

  4. 让我们进一步打破正则表达式:\w*(?=\w*\d)(?=\w*[a-z])(?=\w*[A-Z])\w*

    让我们提供一些等价物:

    1. \w => [a-zA-Z0-9_]
    2. \d => [0-9]
    3. * => 零次或多次
    4. (?=) 是一个先行断言。示例 /a(?=b)/ 这将匹配任何“a”后跟“b”

    5. 这些前瞻的目的:

      • (?=\w*\d) => 检查是否有数字
      • (?=\w*[a-z]) => 检查是否有小写字母
      • (?=\w*[A-Z]) => 检查是否有大写字母
      • 让我们以 (?=\w*\d) 为例:\w* 只是作为一种“解决方法”,以防数字前有 [a-zA-Z0-9_]*

最后,这个正则表达式只是确保输入:

  1. 长度为 6 到 20 个字符
  2. 最少:1 个小写字母、1 个大写字母和 1 个数字
  3. 允许的字符是字母(大写和小写 (a-z,A-Z))、数字和下划线。

三个有趣的网站www.regexper.comwww.regular-expressions.infowww.regex101.com

注意:不要限制密码,无论如何您都必须对其进行哈希处理。看看here 或查看关于 SO 的其他问题。

【讨论】:

  • {6,20} 表示 6 到 20 (不是字符),并且在这种模式中几乎没有影响,因为它适用的组可以是零宽度。跨度>
  • @PhillSparks 感谢您指出这一点:)
  • 感谢@HamZaDzCyber​​DeV。你给了我很大的帮助,感谢你花时间回答我的问题。 :) 感谢菲尔的观点。
  • @GitKidd 啊这也是一个测试/练习/学习正则表达式的好网站regex101.com
【解决方案2】:

实际上,此模式匹配所有包含至少 3 个字符(数字、大写和小写任意顺序)的密码,没有长度限制(正则表达式引擎除外)。所有字符必须是单词字符(即:来自\w 类)。

作者的意图可能是将所有 6 到 20 个单词字符之间的密码与至少一个数字、一个大写和一个小写匹配,正如量词和前瞻所暗示的那样。

简而言之,这种模式是错误的,但可能是针对这种经典密码验证模式的作用:

^(?=\w*[A-Z])(?=\w*[a-z])(?=\w*\d)\w{6,20}$

或者这个没有所有多余的\w:

^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)\w{6,20}$

解释:前瞻是零宽度的断言,它们不消耗字符,它们只是测试。结果它们中的每一个都是从字符串的开头执行的,因为它们被锚定到^。如果每个前瞻都成功,则始终从字符串的开头测试\w{6,20},以确定它是否仅包含 6 到 20 个单词字符。 $ 表示字符串的结尾。

正如 cmets 中所说,这种模式来自拉里·厄尔曼 (Larry Ullman) 所著的“Effortless E-commerce”第一版一书

即使作者写道:

“而且,诚然,即使我也经常需要查找模式的正确语法,但这需要高水平的正则表达式专业知识。”

即使我不同意句子的第二部分,我认为这种模式只是一个简单的错字。不过不知道第二版有没有改正。

【讨论】:

  • 此模式将匹配任何至少有 1 个数字、小写字母和大写字母且仅包含单词字符 [a-zA-Z0-9_] 的字符串。由于在这里使用了\w*,它变得令人困惑,但{6,20} 实际上没有任何效果,因为它可以是 6 到 20 的无(零宽度)。
猜你喜欢
  • 2016-10-09
  • 1970-01-01
  • 2013-01-19
  • 1970-01-01
  • 2016-06-03
  • 2015-06-10
  • 2013-06-01
  • 2016-10-28
相关资源
最近更新 更多