I'm using an ASP.NET
web service that returns an Harbour
array, it's syntax is:
// single dimensional
{ key1, key2, key3 }
// multi dimensional
{
{ key1-value1, key1-value2 },
{ key2-value1, key2-value2, key2-value3 },
{ key3-value1, key3-value2 }
}
Harbour
is an updated version of CA-Clipper
compiler.
Documentation for
Harbour
/CA-Clipper
language: http://harbourminigui.com/clipperng/ngcd9d.php
Is there any way to parse this string into a PHP
array even when the "array" has more than 2 dimensions?
I created a class that can parse this string:
<?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);