Первый 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, поэтому я бы не рекомендовал его использовать.
Больше объяснений
По просьбе @ Кристофер Альтман
Единственный новый бит в версии 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
возвращает массив совпадений (где совпадения являются массивами). Поэтому все, что я делаю, это беру массив и на каждое совпадение применяю функцию, которая преобразует совпадение в другой массив в требуемом формате.