まず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
です。これにより、多くのコード行が不要になります。(配列マップは、配列内のすべての項目に関数を適用し、変換された配列を返します)。素敵なクロージャ構文にはPHP5.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開発者が読みにくいという大きな欠点があるため、使用をお勧めしません。
詳細説明
@ChristopherAltmanのリクエストで
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
は、一致の配列を返します(一致は配列です)。したがって、私が行うのは配列を取得し、一致するたびに、一致を必要な形式の別の配列に変換する関数を適用することです。