#php #регулярные_выражения #pcre
Вообщем требуется превратить #$test.a# в $test['a']. Делаю это так: preg_replace('@\#(\$.+?)\.(.+?)\#@', '$1[\'$2\']', '#$test.a#', -1); Всё работает: https://xrg.es/#1ibiack Но не знаю как превратить #$test.a.b.c# в $test['a']['b']['c']. Помогите... Заранее спасибо!
Ответы
Ответ 1
не знаю как превратить #$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']; Следует помнить, что полученная строка не является массивом, а только выглядит как массив визуально.Ответ 2
Всё можно сделать одной регуляркой с использованием оператора \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']Ответ 3
Как то так preg_replace("@\#(\$.+?)\.(.+?)\.(.+?)\.(.+?)\#@", "$1['$2']['$3']['$4'];", "#$test.a.b.c#", -1); PS. Но если там может быть разное количество переменных, то это будет сложнее сделать.Ответ 4
За входние данные можно взять $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; }
Комментариев нет:
Отправить комментарий