Вообщем требуется превратить #$test.a# в $test['a'].
Делаю это так: preg_replace('@\#(\$.+?)\.(.+?)\#@', '$1[\'$2\']', '#$test.a#', -1);
Всё работает: https://xrg.es/#1ibiack
Но не знаю как превратить #$test.a.b.c# в $test['a']['b']['c'].
Помогите... Заранее спасибо!
Всё можно сделать одной регуляркой с использованием оператора \G:
'~(?:#(\$[^.#]+)(?=\.[^#]*#)|\G(?!^))\.([^#.]+)#?~'
См. демо регулярного выражения.
Подробности
(?:#(\$[^.#]+)(?=\.[^#]*#)|\G(?!^)) - одно из двух:
#(\$[^.#]+)(?=\.[^#]*#) - последовательность:
# - знак #,(\$[^.#]+) - Захватывающая группа №1: $, один и более символов, отличных от . и #(?=\.[^#]*#) - после которых есть знак ., 0+ знаков, отличных от #, а затем #| - или\G(?!^) - позиция в строке после предыдущего удачного совпадения\. - знак .([^#.]+) - Захватывающая группа №2: 1+ знаков, отличных от . и ##? - 1 или 0 знаков #.Пример на PHP:
$re = '@(?:#(\$[^.#]+)(?=\.[^#]*#)|\G(?!^))\.([^#.]+)#?@';
$str = '#$test.a.b.c# #$test.a#';
echo preg_replace($re, '$1[\'$2\']', $str);
// => $test['a']['b']['c'] $test['a']
не знаю как превратить #$test.a.b.c# в $test['a']['b']['c']
Вначале найти совпадения подстроки между решётками '#...#'. Потом разбить найденную подстроку на элементы по символу '.'. Далее, из полученного массива извлечь первый элемент (это название переменной), а оставшуюся часть обработать циклом, собирая строку необходимого формата в результирующую переменную $out:
$str = '#$test.a.b.c#'; // Сработает
$str = '#$test.a#'; // Сработает
$str = '#$test.#'; // Не сработает
$str = '#$test#'; // Не сработает
echo preg_replace_callback(
'~#(\$[a-z]+\d*\.[^#]+)#~',
function ($arr) {
$tmp = explode('.', $arr[1]);
$out = array_shift($tmp);
foreach ($tmp as $i) $out .= "['$i']";
$out .= ';';
return $out;
},
$str
);
Результат
$test['a']['b']['c'];
Следует помнить, что полученная строка не является массивом, а только выглядит как массив визуально.
Как то так
preg_replace("@\#(\$.+?)\.(.+?)\.(.+?)\.(.+?)\#@", "$1['$2']['$3']['$4'];", "#$test.a.b.c#", -1);
PS. Но если там может быть разное количество переменных, то это будет сложнее сделать.
За входние данные можно взять
$string = '#$test_23.a.b.c#';
Напишу небольшую функцию которая будет делать то что нужно и возвращать результат или FALSE если будут невалидные данные
Для начала проверим что слева действительно валидное название переменной.
Оно как известно начинаеться со знака доллара ($) Потом должна идти одна буква латинского алфавита или нижнее подчеркивание ([a-zA-Z_])
Дальше в названии переменной может идти любая цифра, буква латинского алфавита или знак подчеркивания (\w). Символ * указывает на то что их может быть 0 или больше. Тоесть их может и не быть.
Справа может быть или не быть продолжение название переменной
function transform($string){
if(preg_match('@#(\$[a-zA-Z_]\w*)\.?([\w.]+)?#@', $string, $match)){
if(empty($match[2])){
return $match[1];
}
$replace_string = "['" . preg_replace('@(\w)\.@', "$1']['", $match[2]) . "']";
return $match[1] . $replace_string;
}
return FALSE;
}
Сборка персонального компьютера от Artline: умный выбор для современных пользователей