将 Harbor 字符串数组解析为 PHP 数组

Parse Harbour string array into PHP array

我正在使用一个 ASP.NET 网络服务 returns 一个 Harbour 数组,它的语法是:

// single dimensional
{ key1, key2, key3 }

// multi dimensional
{ 
    { key1-value1, key1-value2 }, 
    { key2-value1, key2-value2, key2-value3 },
    { key3-value1, key3-value2 } 
}

HarbourCA-Clipper 编译器的更新版本。

Documentation for Harbour / CA-Clipper language: http://harbourminigui.com/clipperng/ngcd9d.php

即使 "array" 的维度超过 2 维,是否有任何方法可以将此字符串解析为 PHP 数组?

我创建了一个 class 可以解析这个字符串:

<?php

namespace Library;

/**
 * @author (odahcam) <luiz@h2k.com.br>
 *
 * @version 1.0.0
 **/
class Clipper
{
    public function __construct($argument)
    {
        return;
    }

    /**
     * Auxiliar function for self::array().
     *
     * @author odahcam
     *
     * @version 1.0.0
     *
     * @param &{array} $array_string
     *
     * @return {array} $array_php
     **/
    private static function parseArray(&$array_string)
    {
        $array_php = []; // array de saída
        $var_last = ''; // último caractere interpretado
        $key_content = ''; // the content of a $array_php key

        foreach ($array_string as $key => $var) {
            /* Deleta o caractere de referencia antes de interpretá-lo.
             * Isto evita que o caractere seja interpretado duas vezes caso esta
             * função seja chamada novamente, o que irá acontecer.
             */
            unset($array_string[$key]);

            if ($var_last !== '\') {
                switch ($var):
                    case '}':
                    case ',':
                        /* fim de chave ou array.
                         */
                        if ($var_last !== '}' && $var_last !== '{') {
                            $array_php[] = $key_content; // atribui o conteúdo à chave
                            $key_content = ''; // reseta captador de conteúdo de chave
                        }

                        switch ($var):
                            case '}':
                                // logger('retorna array: '.$var.' last: '.$var_last);
                                /* quebra swicth + foreach porque interpretou um
                                 * array completo, então deve retorná-lo.
                                 */
                                break 3;

                            case ',':
                                // logger('retorna chave: '.$var.' last: '.$var_last);
                                /* completou uma chave, então sai dos switchs e
                                 * continua interpretando o array.
                                 */
                                break 2;
                        endswitch;

                        // break;

                    case '{':
                        /* inicio de array.
                         */
                        // logger('gerou array: '.$var.' last: '.$var_last);
                        $array_php[] = self::parseArray($array_string); // interpreta o array vigente e armazena em uma chave
                        /* a função executada na linha anterior já faz a remoção
                         * dos caracteres interpretados em $array_string graças
                         * ao operador & (&$array_string).
                         * Aqui só é necessário sair do switch e continuar interpretando
                         * o restante das chaves deste array.
                         */
                        break;

                    default:
                        $key_content .= $var;
                        break;
                endswitch;
            } else {
                $key_content .= $var;
            }

            $var_last = $var; // define o último caractere interpretado.
        }

        return $array_php;
    }

    /**
     * @author odahcam
     *
     * @version 1.0.0
     *
     * @param {array} $string_user
     *
     * @return {array}
     **/
    public static function matrix($string_user = '{}')
    {
        if (is_string($string_user)) {
            $string_dev = preg_replace('~^{~', '', $string_user); // remove a primeira ocorrência de "{", pois é criada automaticamente.

            $string_dev = preg_replace_callback('~(?<!\\)([\{\,])[\n\r\s]+~', function ($m) {
                return $m[1];
            }, $string_dev); // remove espaços antes de "{" e "," e mantém eles.

            $string_dev = preg_replace('~[\n\r\s]+(?<!\\)(\})~', '}', $string_dev); // remove espaços depois de "}"

            // logger($string_dev);

            $array_string = str_split($string_dev);

            return self::parseArray($array_string);
        } else {
            return $string_user;
        }
    }
}

用法:

var array = \Library\Clipper::matrix(string_array);