Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regex and pattern in a preg_match - PHP to fit 123-23-345

I'm not very good into finding the right automation of a regex, to generate different expression, but when this comes to scripting in PHP, it becomes a pain in my ass. I can't proove myself able to write a pattern in preg_match that would 'fit' expressions like: 123-23-345...123-34-456....12-234-56.....It should be 3 groups of digits, where every group, individualy is left-to-right sorted, and every next group hasn't a digit bigger than the biggest digit of the previous group. This: 123-23-456 would be wrong, as 2 in 23 is smaller than 3 in 123. 123-43-45 is wrong again because 43 should be 34...

This should help me validate a field that may have only that type of content. It should be a regex validation not a function for parsing, splitting...

like image 235
user1840192 Avatar asked Mar 18 '13 06:03

user1840192


People also ask

How do I match a pattern in regex?

To match a character having special meaning in regex, you need to use a escape sequence prefix with a backslash ( \ ). E.g., \. matches "." ; regex \+ matches "+" ; and regex \( matches "(" . You also need to use regex \\ to match "\" (back-slash).

What is the purpose of Preg_match () regular expression in PHP?

The preg_match() function will tell you whether a string contains matches of a pattern.

What does regex 0 * 1 * 0 * 1 * Mean?

Basically (0+1)* mathes any sequence of ones and zeroes. So, in your example (0+1)*1(0+1)* should match any sequence that has 1. It would not match 000 , but it would match 010 , 1 , 111 etc. (0+1) means 0 OR 1. 1* means any number of ones.

What does \\ mean in regex?

The backslash character (\) in a regular expression indicates that the character that follows it either is a special character (as shown in the following table), or should be interpreted literally. For more information, see Character Escapes. Escaped character. Description. Pattern.


2 Answers

Well, there will be no regex-only solution, I think. So here I coded the function you need:

function isValidDigitExpression($string) {
    $flag = preg_match('/^(\d+)\-(\d+)\-(\d+)$/', $string, $matches);
    if (!$flag) return false;

    // Check correct sorting by splitting digit string to array
    for ($i = 1; $i <= 3; $i++ ) {
         $block[$i] = str_split($matches[$i]);
         $compare = $block[$i];
         sort($compare);
         if ($compare != $block[$i]) return false;
    }

    // Compare Min and Max digits of neighboring digit blocks
    return (max($block[1]) <= min($block[2]) and max($block[2]) <= min($block[3]));
}

$string = "123-34-356"; // Failure, because 3 < 4 comparing Block 2 and Block 3
echo isValidDigitExpression($string) ? "SUCCESS" : "FAILURE";
like image 165
Aranxo Avatar answered Oct 27 '22 00:10

Aranxo


Instead of using only preg_ function, you'd need to use some other condition matching too.

<?php
  $str = "123-34-456";
  preg_match( "/^.*?(\d)\-(\d).*?(\d)\-(\d)/", $str, $matches );
  $flag = true;
  if( $matches[2] < $matches[1] )
      $flag = false;
  if( $matches[4] < $matches[3] )
      $flag = false;
  echo ( !$flag ) ? "ERROR" : "NO ERROR";
?>

Similarly, you can match the numbers in respective sections, iterate over all the literals and again use the flag for not-matching values.

Something like this:

<?php
  $str = "132-34-456";
  preg_match( "/^(\S+)\-(\S+)\-(\S+)$/", $str, $matches );
  $flag = true;
  for( $i = 0; $i < strlen($matches[1]) - 1; $i++ ) {
      if( $matches[1][$i+1] < $matches[1][$i] ) {
          $flag = false;
          break;
      }
  }
  for( $i = 0; $i < strlen($matches[2]) - 1; $i++ ) {
      if( $matches[2][$i+1] < $matches[2][$i] ) {
          $flag = false;
          break;
      }
  }
  for( $i = 0; $i < strlen($matches[3]) - 1; $i++ ) {
      if( $matches[3][$i+1] < $matches[3][$i] ) {
          $flag = false;
          break;
      }
  }
  echo ( !$flag ) ? "ERROR" : "NO ERROR";
?>

Obviously, this is not the best/most-optimized of the solution.

like image 26
hjpotter92 Avatar answered Oct 27 '22 00:10

hjpotter92