문제

Good day. I have a problem with a regular expression, I'm really stuck, the problem is that the field I'm trying to extract could be composed like:

NULL

Name#Size^Value#XXL^Quantity#3

Name#Size^Value#S^Name#Color^Value#Black^Quantity#2

The size will be always the first, color (optional) the second value, quantity the last. of course I would like to obtain those values to insert them in a database.

actually I have done this:

$txt='Name#Size^Value#S^Name#Color^Value#Black^Quantity#2';

  $re1='(Name#Size\\^Value#)';  
  $re2='((?:[a-z][a-z0-9_]*))'; 
  $re3='(\\^Name#Color\\^Value#)';  
  $re4='((?:[a-z][a-z0-9_]*))';
  $re5='(\\^Quantity#)';    
  $re6='(\\d+)';    

  if ($c=preg_match_all ("/".$re1.$re2.$re3.$re4.$re5.$re6."/is", $txt, $matches))
  {
      $word1=$matches[1][0];      
      $var1=$matches[2][0];
      $word2=$matches[3][0];
      $var2=$matches[4][0];
      $word3=$matches[5][0];
      $int1=$matches[6][0];
      print "<br> Size: $var1 <br> Color: $var2 <br> Quantity: $int1";
  }

but i'm not sure on how I can match the color as optional (and in that case take the quantity as second parameter.

Anyone could help me in this? It should be all wrong.. in that case, please point me in the good direction.

도움이 되었습니까?

해결책 3

There is no need to do this with regex. You can solve it easily by splitting the string twice based on some rules.

Update: Here's the php code. Will work without a single regular expression, also for more complex combinations of these properties.

function split_string($string) {
  $properties = Array();
  $pairs = explode('^', $string);
  while ($pairs) {
    $first_pair = split('#', array_shift($pairs));
    if ($first_pair[0] == 'Name') {
      $second_pair = split('#', array_shift($pairs));
      $properties[$first_pair[1]] = $second_pair[1];
    } else {
      $properties[$first_pair[0]] = $first_pair[1];
    }
  }
  return $properties;
}

print_r(split_string("Name#Size^Value#S^Name#Color^Value#Black^Quantity#2"));
print_r(split_string("Name#Size^Value#XXL^Quantity#3")); 

Output:

Array
(
    [Size] => S
    [Color] => Black
    [Quantity] => 2
)
Array
(
    [Size] => XXL
    [Quantity] => 3
)

다른 팁

Add ? in the end of the regexp of the color to match the color optionally

What about something drastically simpler like this:

(?:name#(\w+?)\^)?(?:value#(\w+?)\^)?(?:quantity#(\d+?))?

http://regex101.com/r/nN4yT3

Since your last bit (Quantity) doesn't follow the pattern, it ends up a bit goofy in the second capture group; in that respect, it might be easier to use named capture groups:

(?:name#(?<name>\w+?)\^)?(?:value#(?<value>\w+?)\^)?(?:quantity#(?<quantity>\d+?))?

Just need the optional quantifier (as others say).
But, it might be maintained better as -
(note - am not a php guru)

$re =
'/
     Name\#Size\^Value\#
     ( [a-z] [a-z0-9_]* )               # (1)
     \^Name\#Color\^Value\#
     ( [a-z] [a-z0-9_]* )?              # (2)
     \^Quantity\#
     ( \d+ )                            # (3)
/xi';

if ( preg_match_all ( $re, $txt, $matches ))
{
      $var1 = $matches[1][0];
      $var2 = $matches[2][0];
      $var3 = $matches[3][0];
      print "<br> Size: $var1 <br> Color: $var2 <br> Quantity: $var3";
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top