1

I am using preg_match_all to ensure that a string follows a certain pattern.

It should display 'all conditions are met' becuase the string follows the pattern, but instead, it displays 'conditions net met'.

$order = "item[]=2&item[]=1&item[]=3&item[]=4&item[]=5&item[]=6&item[]=7&item[]=8&item[]=9&item[]=10&item[]=11&item[]=12";
$pattern = "/^(item\[\]=([1-9]|10|11|12))(&(item\[\]=([1-9]|10|11|12))){11}$/";

if(preg_match($pattern, $order)) {

   // check for repetition
   $matches = [];
   preg_match_all("/\d+/", $order, $matches);
   if(count(array_count_values($matches[0])) == 12) {
      // All are unique values
      echo 'All conditions met';
   }
}else{
   echo 'Conditions not met';
}
The Codesee
  • 3,714
  • 5
  • 38
  • 78

3 Answers3

1

The right way would be using
parse_str(to parse quesry string: key/value pairs separated with &)
and array_diff(to check if all numbers from the needed range 1-12 are present and not repeated) functions:

$order = "item[]=2&item[]=1&item[]=3&item[]=4&item[]=5&item[]=6&item[]=7&item[]=8&item[]=9&item[]=10&item[]=11&item[]=12";
parse_str($order, $items);

if (isset($items['item']) && is_array($items['item'])
    && count($items['item']) == 12 && !array_diff(range(1, 12), $items['item'])) {
    echo 'All conditions met';
} else {
    echo 'Conditions not met';
}
RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105
  • Should I post this answer also on http://stackoverflow.com/questions/42679522/make-sure-that-string-follows-the-required-format/ or would you like to? – The Codesee Mar 09 '17 at 15:54
  • @TheCodesee, I think it's not nessesary, but you can specify "related to" in each of the questions to make this questions linked. Like *cross-linking* – RomanPerekhrest Mar 09 '17 at 15:58
0

Try this:

<?php

$order = "item[]=2&item[]=1&item[]=3&item[]=4&item[]=5&item[]=6&item[]=7&item[]=8&item[]=9&item[]=10&item[]=11&item[]=12";
$pattern = "/^(item\[\]=([1-9]|10|11|12))(&(item\[\]=([1-9]|10|11|12))){11}$/";

if(preg_match($pattern, $order)) {

   // check for repetition
   $matches = [];
   preg_match_all("/\d+/", $order, $matches);
   if(count(array_count_values($matches[0])) == $movienumber) {
       // All are unique values
       echo 'All conditions met';
    }
}else{
   echo 'Conditions not met';
}

You were missing a ) in pattern.

Ataur Rahman
  • 1,671
  • 14
  • 12
0

Assuming the input string is valid (all conditions are met) when it contains in item[] all the values from 1 to 12, this simple piece of code works faster than preg_match() and it's easier to understand:

// Input string
$order = "item[]=2&item[]=1&item[]=3&item[]=4&item[]=5&item[]=6&item[]=7&item[]=8&item[]=9&item[]=10&item[]=11&item[]=12";

// Parse it to values and store them in $pieces
$pieces = array();
parse_str($order, $pieces);

// Need to sort the values to let the comparison succeed
sort($pieces['item']);
$valid = ($pieces['item'] == range(1, 12));

// Verification
var_dump($valid);
// It prints:
// bool(true)
axiac
  • 68,258
  • 9
  • 99
  • 134