вот вам простое рекурсивное решение
function repl($str, $map) {
if(strlen($str) == 0)
return array('');
$out = array();
foreach(repl(substr($str, 1), $map) as $r)
foreach($map[$str[0]] as $sub)
$out[] = $sub . $r;
return $out;
}
используйте вот так
$map = array(
'a' => array('1', '2', '3'),
'b' => array('@', '*'),
'c' => array('X', 'Y', 'Z')
);
$result = repl("abc", $map);
Для работы со строками utf8 (или произвольными подстроками) функция должна принимать массив строк:
function repl($chars, $map) {
if(count($chars) == 0)
return array('');
$out = array();
foreach(repl(array_slice($chars, 1), $map) as $r)
foreach($map[$chars[0]] as $sub)
$out[] = $sub . $r;
return $out;
}
используйте вот так
preg_match_all('~.~u', $str, $m);
$chars = $m[0];
$result = repl($chars, $map);