php:“sscanf”来'消耗'一个字符串但允许缺少参数

时间:2011-05-24 20:02:21

标签: php scanf

这是针对 osCommerce 贡献的 (“自动将多个带有属性的产品从外部源添加到购物车”)

这个现有代码使用sscanf来“爆炸”代表一个字母的字符串 - 产品ID,
- 产品选项,
- 和数量:

sscanf('28{8}17[1]', '%d{%d}%d[%f]', 
  $productID,                       // 28
  $productOptionID, $optionValueID, //{8}17 <--- Product Options!!!
  $productQuantity                  //[1]
);

如果只有1套“产品选项”(例如{8} 17),那么效果很好。

但是这个过程需要进行调整,以便它可以处理多个产品选项,并将它们放入一个数组中,例如:

'28{8}17{7}15{9}19[1]' //array(8=>17, 7=>15, 9=>19)
OR
'28{8}17{7}15[1]'      //array(8=>17, 7=>15)
OR
'28{8}17[1]'           //array(8=>17)

提前致谢。 (我是一名pascal程序员)

2 个答案:

答案 0 :(得分:3)

您不应该尝试使用一个sscanf进行复杂的递归解析。把它粘在一个循环中。类似的东西:

<?php

$str = "28{8}17{7}15{9}19[1]";
#$str = "28{8}17{7}15[1]";
#$str = "28{8}17[1]";
sscanf($str,"%d%s",$prod,$rest);
printf("Got prod %d\n", $prod);
while (sscanf($rest,"{%d}%d%s",$opt,$id,$rest))
 {
   printf("opt=%d id=%d\n",$opt,$id);
 }
sscanf($rest,"[%d]",$quantity);
printf("Got qty %d\n",$quantity);
?>

答案 1 :(得分:1)

也许正则表达式可能很有趣

$a = '28{8}17{7}15{9}19[1]';
$matches = null;
preg_match_all('~\\{[0-9]{1,3}\\}[0-9]{1,3}~', $a, $matches);

获取其他东西

$id = (int) $a; // ;)
$quantity = substr($a, strrpos($a, '[')+ 1, -1);

根据评论稍微更新

$a = '28{8}17{7}15{9}19[1]';
$matches = null;
preg_match_all('~\\{([0-9]{1,3})\\}([0-9]{1,3})~', $a, $matches, PREG_SET_ORDER);
$result = array();
foreach ($matches as $entry) {
  $result[$entry[1]] = $entry[2];
}