Пишу, по большей части, про историю, свою жизнь и немного про программирование.

Преобразование tnsnames.ora в JSON

По работе сделал разбор файла tnsnames.ora — файла оракловой конфигурации на ПХП в массив:

function Ora2Array($str)
{
    // убираю комментарии
    $str = preg_replace('/^\s*#.*$/m', '', $str);

    // преобразование скаляров
    $str = preg_replace('/\((\w+)\s*=\s*([^()]+)\)/m', '"$1": "$2", ', $str);

    // преобразование ассоциативных массивов
    do {
        $str = preg_replace('/\((\w+)\s*=\s*([^()]+?)[\s,]*\)/sS', '"$1": { $2 },', $str, -1, $count);
    } while ($count);

    // преобразование верхнеуровневых значений
    $str = preg_replace('/(\w+)\s*=\s*([^()]+?)[\s,]*(?:(?=\w+\s*=)|\s*$)/s', '"$1": { $2 },', $str);

    return json_decode('{' . trim($str, ' ,') . '}', true);
}

Не разбираются значения в кавычках — такого в наших конфигурациях не встречается, но добавляется несложно.

2 комментария
rjhdby 2017

Не работает для случаев с несколькими полями ADDRESS, например так:

BYYDB_TR =
        (DESCRIPTION=
                       (LOAD_BALANCE=on)
                       (FAILOVER=on)
                       (ADDRESS=(PROTOCOL=tcp)(HOST=byydbn)(PORT=1526))
                       (ADDRESS=(PROTOCOL=tcp)(HOST=byydb)(PORT=1526))
                       (ADDRESS=(PROTOCOL=tcp)(HOST=ctdbn)(PORT=1528))
                       (ADDRESS=(PROTOCOL=tcp)(HOST=ctdb)(PORT=1528))
                       (CONNECT_DATA=(SERVICE_NAME=bmbdb_service)(FAILOVER_MODE=(TYPE=select)(METHOD=basic)))
                 )
         )

Евгений Степанищев (bolknote.ru) 2017

Комментарий для rjhdby:

Вероятно. Но у меня не было цели делать универсально. Добавьте сами.