首先explode()
是带有分隔符的数组*
然后,您可以使用 preg_match_all 匹配展开数组中的每个项目。像这样的东西适用于您的示例输入。
$layout = explode('*', $input);
$columns = array();
foreach ( $layout as $item ){
$parts = array();
//matches either a -, x or + followed by one or more digits
preg_match_all('/([+-x])(\d+)/', $item, $matches, PREG_SET_ORDER);
foreach ( $matches as $match){
//match[1] hold the + or -, match[2] holds the digits
$parts[] = array($match[1], $match[2]);
}
$columns[] = $parts;
}
您的示例的输出结果如下:
array(
array( array('+', '2'), array('-', '1'), array('+', '18') ),
array( array('+', '7'), array('-', '21'), array('+', '3') ),
//etc
);
使用 PHP 5.3,您可以使用类似的东西(未经测试)。主要区别在于内部循环已被替换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
);
稍微扩展和改变它(例如)
//bind an anonymous function to the variable $func
$func = function($a){
return $a*$a;
};
//$func() now calls the anonymous function we have just defined
//then we can call it like so:
$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
返回一个匹配数组(其中匹配是数组)。所以我所做的就是获取数组,并在每次匹配时应用一个函数,将匹配转换为所需格式的不同数组。