带有可选模式的复杂正则表达式

时间:2014-03-03 21:40:43

标签: php regex string

美好的一天。 我有一个正则表达式的问题,我真的卡住了,问题是我想要提取的字段可以组成如下:

NULL

Name#Size^Value#XXL^Quantity#3

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

尺寸始终是第一个,颜色(可选)是第二个值,数量是最后一个。 当然我想获取这些值以将它们插入数据库中。

实际上我已经这样做了:

$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";
  }

但我不确定如何将颜色与可选颜色相匹配(在这种情况下,将数量作为第二个参数。

任何人都可以帮助我吗? 这应该是全错的......在这种情况下,请指出我的方向。

4 个答案:

答案 0 :(得分:2)

添加?在颜色的正则表达式的末尾,以匹配颜色任选

答案 1 :(得分:2)

这样的事情简单得多:

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

http://regex101.com/r/nN4yT3

由于您的最后一位(数量)不遵循该模式,因此在第二个捕获组中它会变得有点愚蠢;在这方面,使用命名捕获组可能更容易:

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

答案 2 :(得分:1)

没有必要使用正则表达式执行此操作。您可以根据某些规则将字符串拆分两次,从而轻松解决问题。

更新:这是php代码。在没有单个正则表达式的情况下工作,也适用于这些属性的更复杂组合。

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")); 

输出:

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

答案 3 :(得分:0)

只需要可选的量词(正如其他人所说) 但是,它可能会更好地保持为 -
(注意 - 我不是一个php大师)

$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";
}
相关问题