V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
nyse
V2EX  ›  PHP

[正则表达式] 怎么理解 正\反向 肯\否定预查?以及理解判断密码强度的表达式?

  •  
  •   nyse · 2019-06-28 09:37:37 +08:00 · 3558 次点击
    这是一个创建于 2001 天前的主题,其中的信息可能已经有所发展或是发生改变。
    print_r(preg_match('/(?=[A-Z])[a-z][0-9]/', 'Ab0', $m)); //0
    
    print_r($m); //Array()
    

    (?=[A-Z]) 这个的意思不是对整个字符串进行预匹配,不占用字符,后面的 [a-z][0-9] 才正式开始匹配,为什么匹配不到 b0 ?

    还有就是怎么理解匹配密码强度这个表达式:

    (?=^.{8,}$)(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?!.*\n).*$

    8 条回复    2019-06-28 10:58:14 +08:00
    ChenFanlin
        1
    ChenFanlin  
       2019-06-28 10:24:38 +08:00
    https://zhuanlan.zhihu.com/p/27309508 这里有对预查的理解
    我也是小菜鸡,互相讨论下. _A_b_0_ , 先加上`_`来代替位置,
    (?=[A-Z])是匹配[A-Z]前面的位置(就是那个_), 匹配到了之后, 然后再寻找[a-z]
    换成(?![A-Z])[a-z][0-9]就可以了
    https://regex101.com/ 在这里可以看每一步匹配的步骤
    whosesmile
        2
    whosesmile  
       2019-06-28 10:31:12 +08:00
    `/(?=[A-Z])[a-z][0-9]/ `
    这个表达式不对,?=表示前向匹配,意味着匹配断言前面的字符,而你这个是匹配断言后面的字符;所以你这个表达式应该改为后向断言:
    `/(?<=[A-Z])[a-z][0-9]/`
    nyse
        3
    nyse  
    OP
       2019-06-28 10:36:22 +08:00
    @whosesmile #2

    意思是说 ?= 的必须在其他原子后面,?<= 才能在其他原子前面?
    whosesmile
        4
    whosesmile  
       2019-06-28 10:41:39 +08:00
    @nyse 不完全是这个意思,而是如果你仅仅匹配位置,当然无所谓位置;你看你的那个密码复杂度就是仅匹配位置,但是不要求匹配结果;
    但是如果你意图匹配特定位置字符,那么对位置前后有要求了。
    ltux
        5
    ltux  
       2019-06-28 10:45:29 +08:00
    你字符串是,Ab0,(?=[A-Z]) 先看一下右边是不是[A-Z],结果看到了 A,于是开始匹配[a-z][0-9],但是你字符串是 Ab0,于是[a-z]匹配失败。
    (?=[A-Z])不占用字符,即 Ab0 中的 A 不会被消耗,[a-z][0-9]依旧从最开头的 A 开始匹配。
    whosesmile
        6
    whosesmile  
       2019-06-28 10:45:42 +08:00
    ```javascript
    /(?=\d+)/.test('a123456b'); // true
    /a(?=\d+)/.test('a123456b'); // true
    /(?=\d+)b/.test('a123456b'); // false
    ```
    whosesmile
        7
    whosesmile  
       2019-06-28 10:56:14 +08:00   ❤️ 1
    @ltux 我觉得这个解释不太正确,因为这个正则并没有添加行首位置匹配;按你的解释即便从头开始,也应该正确,因为 /[a-z][0-9]/对于'Ab0'是匹配的,仅对于 /^[a-z][0-9]/是不匹配的。但是具体为什么错误,我也不理解,大改规则如此。
    Aixtuz
        8
    Aixtuz  
       2019-06-28 10:58:14 +08:00
    之前读的这篇文章: https://deerchao.net/tutorials/regex/regex.htm

    (?=exp)也叫零宽度正预测先行断言,它断言自身出现的位置的后面能匹配表达式 exp。比如\b\w+(?=ing\b),匹配以 ing 结尾的单词的前面部分(除了 ing 以外的部分),如查找 I'm singing while you're dancing.时,它会匹配 sing 和 danc。

    (?<=exp)也叫零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式 exp。比如(?<=\bre)\w+\b 会匹配以 re 开头的单词的后半部分(除了 re 以外的部分),例如在查找 reading a book 时,它匹配 ading。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3081 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 13:12 · PVG 21:12 · LAX 05:12 · JFK 08:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.