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).*$
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/ 在这里可以看每一步匹配的步骤 |
2
whosesmile 2019-06-28 10:31:12 +08:00
`/(?=[A-Z])[a-z][0-9]/ `
这个表达式不对,?=表示前向匹配,意味着匹配断言前面的字符,而你这个是匹配断言后面的字符;所以你这个表达式应该改为后向断言: `/(?<=[A-Z])[a-z][0-9]/` |
3
nyse OP |
4
whosesmile 2019-06-28 10:41:39 +08:00
@nyse 不完全是这个意思,而是如果你仅仅匹配位置,当然无所谓位置;你看你的那个密码复杂度就是仅匹配位置,但是不要求匹配结果;
但是如果你意图匹配特定位置字符,那么对位置前后有要求了。 |
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 开始匹配。 |
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 ``` |
7
whosesmile 2019-06-28 10:56:14 +08:00 1
@ltux 我觉得这个解释不太正确,因为这个正则并没有添加行首位置匹配;按你的解释即便从头开始,也应该正确,因为 /[a-z][0-9]/对于'Ab0'是匹配的,仅对于 /^[a-z][0-9]/是不匹配的。但是具体为什么错误,我也不理解,大改规则如此。
|
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。 |