基本上,我只是想知道是否存在这样的函数:
$string = 'helloWorld';
// 1 uppercase, 1 lower case, 1 number and at least 8 of length
$regex = '/^'S*(?='S{8,})(?='S*[a-z])(?='S*[A-Z])(?='S*['d])'S*$/'
$percent = matchPercent($string, $regex);
echo "the string match {$percent}% of the given regex";
然后,结果可能是这样的:
字符串匹配给定正则表达式的 75%
看到另一个帖子和问题,我可以做一些这样的事情:
$uppercase = preg_match('@[A-Z]@', $password);
$lowercase = preg_match('@[a-z]@', $password);
$number = preg_match('@[0-9]@', $password);
但是,目标是在函数中使用任何正则表达式模式
如果你想以正则表达式的方式并根据你提供的用例来做到这一点,我们需要使整个正则表达式成为可选的。此外,我们还将在展望中使用捕获组。
但首先,让我们改进您的正则表达式:
-
['d]
是多余的,只需使用'd
即可。 -
'S*(?='S{8,})
删除'S*
部分,我们已经在最后有了它。
我们的正则表达式看起来像^(?='S{8,})(?='S*[a-z])(?='S*[A-Z])(?='S*'d)'S*$
现在是棘手的部分,我们将在展望中添加组并使它们可选:
^(?=('S{8,})?)(?=('S*[a-z])?)(?=('S*[A-Z])?)(?=('S*'d)?)'S*$
你可能会问为什么?创建这些组是为了我们以后可以跟踪它们。我们将它们设置为可选,以便我们的正则表达式始终匹配。这样,我们就可以做一些数学运算了!
$regex = '~^(?=('S{8,})?)(?=('S*[a-z])?)(?=('S*[A-Z])?)(?=('S*'d)?)'S*$~';
$input = 'helloWorld';
preg_match_all($regex, $input, $m);
array_shift($m); // Get rid of group 0
for($i = 0, $j = $k = count($m); $i < $j; $i++){ // Looping
if(empty($m[$i][0])){ // If there was no match for that particular group
$k--;
}
}
$percentage = round(($k / $j) * 100);
echo $percentage;
在线 php 演示
编辑
:我看到Hamza也有几乎同样的想法。
确定!这是一个非常有趣的问题。
下面是简化验证正则表达式的解决方案。
$str = 'helloword';
$regex = '~^(?=('S{8,}))?(?=('S*[a-z]))?(?=('S*[A-Z]))?(?=('S*['d]))?.*$~';
if(preg_match($regex,$str,$m)) {
$totaltests = 4;
$passedtests = count(array_filter($m)) -1 ;
echo $passedtests / $totaltests;
}
输出:0.5
它是如何工作的?
- 对于每个条件(由前瞻表示(,我们捕获可以匹配的文本。
- 我们将
$totaltests
定义为测试的总数 - 我们计算通过的测试数量,
count(array_filter($m)) -1
删除空组和组 0,即整体匹配。 - 我们分裂。