How many percent of the string matches the regular expression

Basically, I'm just wondering if such a function exists:

$string = 'helloWorld'; // 1 uppercase, 1 lower case, 1 number and at least 8 of length $regex = '/^\S*(?=\S{8,})(?=\S*[az])(?=\S*[AZ])(?=\S*[\d])\S*$/' $percent = matchPercent($string, $regex); echo "the string match {$percent}% of the given regex"; 

Then the result could be something like this:

the string matches 75% of the given regular expression

After seeing another post and question, I can do something like this:

 $uppercase = preg_match('@[AZ]@', $password); $lowercase = preg_match('@[az]@', $password); $number = preg_match('@[0-9]@', $password); 

But the goal is to work with any regex pattern in a function

+3
source share
2 answers

If you want to do this in a regular manner and based on the use case that you have provided, we need to make the entire regular expression complementary. We will also use capture groups in our forecasts.

But first, create a regex:

  • [\d] is redundant, just use \d .
  • \S*(?=\S{8,}) delete the part \S* , we already have it at the end.

Our regular expression will look like ^(?=\S{8,})(?=\S*[az])(?=\S*[AZ])(?=\S*\d)\S*$

Now this is the hard part, we will add groups to our views and make them optional:

^(?=(\S{8,})?)(?=(\S*[az])?)(?=(\S*[AZ])?)(?=(\S*\d)?)\S*$

You may ask why? Groups are created so that we can track them later. We make them optional so that our regular expression always matches. So we can do some math!

 $regex = '~^(?=(\S{8,})?)(?=(\S*[az])?)(?=(\S*[AZ])?)(?=(\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; 

Online php demo

+5
source

EDIT: I see Hamza had almost the same idea.

Sure! This is a very funny question.

Here is a solution for simplified regular expression.

 $str = 'helloword'; $regex = '~^(?=(\S{8,}))?(?=(\S*[az]))?(?=(\S*[AZ]))?(?=(\S*[\d]))?.*$~'; if(preg_match($regex,$str,$m)) { $totaltests = 4; $passedtests = count(array_filter($m)) -1 ; echo $passedtests / $totaltests; } 

Output: 0.5

How it works?

  • For each condition (expressed by gaze) we fix a text that can be matched.
  • Define $totaltests as the total number of tests
  • We count the number of tests passed using count(array_filter($m)) -1 , which removes empty groups and group 0, i.e. general compliance.
  • We are sharing.
+2
source

Source: https://habr.com/ru/post/978321/


All Articles