首先,使用分隔符*
对数组进行explode()
操作。
然后,您可以使用preg_match_all
匹配分割后数组中的每个项。以下是使用您提供的示例输入的代码示例。
$layout = explode('*', $input);
$columns = array();
foreach ( $layout as $item ){
$parts = array();
preg_match_all('/([+-x])(\d+)/', $item, $matches, PREG_SET_ORDER);
foreach ( $matches as $match){
$parts[] = array($match[1], $match[2]);
}
$columns[] = $parts;
}
你的示例代码的输出结果如下所示:
array(
array( array('+', '2'), array('-', '1'), array('+', '18') ),
array( array('+', '7'), array('-', '21'), array('+', '3') ),
);
使用PHP 5.3,您可以尝试以下代码(未经测试)。主要区别是内部循环已被替换为array_map
,这样就不需要很多代码行了。(Array map将函数应用于数组中的每个项,并返回转换后的数组)。漂亮的闭包语法需要PHP 5.3支持。
$layout = explode('*', $input);
$columns = array();
foreach ( $layout as $item ){
preg_match_all('/([+-x])(\d+)/', $item, $matches, PREG_SET_ORDER);
$columns[] = array_map( function($a){ return array($a[1], $a[2]); },
$matches);
}
您可以完全删除循环:
$innerMatch = function($item){
preg_match_all('/([+-x])(\d+)/', $item, $matches, PREG_SET_ORDER);
return array_map( function($a){ return array($a[1], $a[2]); },
$matches);
};
$columns = array_map($innerMatch, explode('*', $input));
然而,这种方法的缺点是大多数PHP开发者都无法读懂它,因此我不建议使用它。
更多解释
应@Christopher Altman的要求
PHP 5.3版本中唯一新增的部分就是这个:
array_map(
function($a){ return array($a[1], $a[2]); },
$matches
);
将其扩展和修改一些(以示例为例)
$func = function($a){
return $a*$a;
};
$result = array_map($func, $myArray);
如果$myArray
被定义为:
array(1,2,3,4);
当使用数组映射函数时,你可以将其视为转换为。
array(func(1),func(2),func(3),func(4));
但是由于PHP不是一种惰性求值的语言,所有函数都会在遇到时立即被计算,因此数组会作为array_map的返回值被返回:
array(2, 4, 9, 16)
在实际代码中,
preg_match_all
返回一组匹配结果(其中每个匹配结果都是一个数组)。因此,我所做的就是取出该数组,并对每个匹配结果应用一个函数,将其转换为所需格式的不同数组。
$column1 = array('+' => 2, '-' => 1, '+' => 18)
是不可能的结果,因为在同一个数组/子数组中两个键不能相同。 - mickmackusa