Page 1 sur 2

string avec virgules et parenthèse en array

Posté : 05 juin 2019, 12:29
par leiopar
Bonjour
existe t'il une méthode élégante de convertir une chaine de caractère ressemblant à ça :

Code : Tout sélectionner

"(a,b,(c,d),((e,f),g),h)"
en un tableau ressemblant à ça :

Code : Tout sélectionner

Array ( [0] => a [1] => b [2] => Array ( [0] => c [1] => d ) [3] => Array ( [0] => Array ( [0] => e [1] => f ) [1] => g ) [4] => h )
sachant que je n'ai aucune idée du nombre d'imbrication de parenthèse ?

Re: string avec virgules et parenthèse en array

Posté : 05 juin 2019, 14:09
par Saian
Je ne sais pas si c'est élégant mais voici une solution toute bête en exploitant la fonction json_decode de php. A voir si tu veux mettre des éléments un peu plus complexes dans ta chaîne que des simples lettres.
$string = "(a,b,(c,d),((e,f),g),h)";
echo "string = $string<br/>";

function stringToArray($string) {
  $string = str_replace(array('(', ')'), array('[', ']'), $string);
  $string = preg_replace('`(\w+)`', '"$1"', $string);

  return json_decode($string);
}

echo '<pre>';
print_r(stringToArray($string));
echo '</pre>';

Sortie :
string = (a,b,(c,d),((e,f),g),h)

Array
(
    [0] => a
    [1] => b
    [2] => Array
        (
            [0] => c
            [1] => d
        )

    [3] => Array
        (
            [0] => Array
                (
                    [0] => e
                    [1] => f
                )

            [1] => g
        )

    [4] => h
)

Re: string avec virgules et parenthèse en array

Posté : 06 juin 2019, 10:15
par leiopar
Effectivement, pour exemple simple, ça marche ... mais en situation réel, j'ai plutôt des truc qui resemble à ça :

Code : Tout sélectionner

string = "('1xrWb_VEHEZRY9JJ9v3lYY',#41,'Default',$,$,#619,$,$,.ELEMENT.,(44,59,59,999999),(4,59,59,999999),150000.,$,$)"
et là, ta fonction ne retourne rien :(

Apparemment, les simple cote, les dièses et les points pose problème ...

Re: string avec virgules et parenthèse en array

Posté : 06 juin 2019, 10:28
par Saian
Oui dans ce cas faut adapter l'expression régulière qui n'était faite que pour capturer des mots. En prenant tout sauf virgules et crochets :
$string = "('1xrWb_VEHEZRY9JJ9v3lYY',#41,'Default',$,$,#619,$,$,.ELEMENT.,(44,59,59,999999),(4,59,59,999999),150000.,$,$)";
echo "string = $string<br/>";

function stringToArray($string) {
  $string = str_replace(array('(', ')'), array('[', ']'), $string);
  $string = preg_replace('`([^,\[\]]+)`', '"$1"', $string);

  return json_decode($string);
}

echo '<pre>';
print_r(stringToArray($string));
echo '</pre>';

Sortie :
string = ('1xrWb_VEHEZRY9JJ9v3lYY',#41,'Default',$,$,#619,$,$,.ELEMENT.,(44,59,59,999999),(4,59,59,999999),150000.,$,$)

Array
(
    [0] => '1xrWb_VEHEZRY9JJ9v3lYY'
    [1] => #41
    [2] => 'Default'
    [3] => $
    [4] => $
    [5] => #619
    [6] => $
    [7] => $
    [8] => .ELEMENT.
    [9] => Array
        (
            [0] => 44
            [1] => 59
            [2] => 59
            [3] => 999999
        )

    [10] => Array
        (
            [0] => 4
            [1] => 59
            [2] => 59
            [3] => 999999
        )

    [11] => 150000.
    [12] => $
    [13] => $
)

Re: string avec virgules et parenthèse en array

Posté : 06 juin 2019, 10:37
par leiopar
Génial !!!
Merci à toi Saian :-)

Re: [RESOLU] string avec virgules et parenthèse en array

Posté : 06 juin 2019, 12:23
par leiopar
Question limite or sujet : comment fait on l'opération inverse ?
(se sent que je vais rapidement avoir besoin de ça)

Re: string avec virgules et parenthèse en array

Posté : 06 juin 2019, 12:43
par Saian
Comme ça : :wink:
function arrayToString($array)
{
  $string = json_encode($array);
  $string = str_replace(array('[', ']', '"'), array('(', ')', ''), $string);

  return $string;
}

Re: string avec virgules et parenthèse en array

Posté : 06 juin 2019, 13:52
par leiopar
Royal !
encore merci ==> RESOLU

Re: [RESOLU] string avec virgules et parenthèse en array

Posté : 13 juin 2019, 15:20
par leiopar
Arf ... ya un problème quand un élément chaine de caractère (entre simple cote) contient des parenthèse, genre ça :

Code : Tout sélectionner

(a,'chaine avec (parenthèse) dedans',(c,d),((e,f),g),h)
Comment, par exemple, les remplacer momentanément mais sans remplacer les autres parenthèses qui définissent les ensemble ?

Re: string avec virgules et parenthèse en array

Posté : 13 juin 2019, 15:55
par Saian
Forcément ça complique un peu les choses... avec ça, ça supportera également les crochets ^^
function stringToArray($string) {
  /* escape some chars */
  $string = str_replace(array('[', ']'), array(':ob:', ':cb:'), $string);
  $string = preg_replace_callback("`'(.*?)'`", function ($matches) {
      return "'".str_replace(array('(', ')'), array(':op:', ':cp:'), $matches[1])."'";
    }, $string);
  
  /* jsonify string */
  $string = preg_replace('`([^,\(\)]+)`', '"$1"', $string);
  $string = str_replace(array('(', ')'), array('[', ']'), $string);

  $array = json_decode($string);
  return restoreEscaped($array);
}
function restoreEscaped($array)
{
  return array_map(function ($entry) {
    return is_array($entry)
      ? restoreEscaped($entry)
      : str_replace(
          array(':ob:', ':cb:', ':op:', ':cp:'),
          array('[', ']', '(', ')'),
          $entry);
    }, $array);
}

function arrayToString($array)
{
  $array = escapeBrackets($array);
  $string = json_encode($array);
  $string = str_replace(array('[', ']', '"', ':ob:', ':cb:'), array('(', ')', '', '[', ']'), $string);

  return $string;
}
function escapeBrackets($array) {
  return array_map(function ($entry) {
    return is_array($entry)
      ? escapeBrackets($entry)
      : str_replace(
          array('[', ']'),
          array(':ob:', ':cb:'),
          $entry);
  }, $array);
}

Re: string avec virgules et parenthèse en array

Posté : 13 juin 2019, 16:44
par leiopar
J'était en train de me battre avec ça :

Code : Tout sélectionner

function param2tab($ifcParam){ // mise en tableau des parametres $ifcParam=preg_replace("#('.*)\((.*')#","$1&#40;$3",$ifcParam); $ifcParam=preg_replace("#('.*)\)(.*')#","#$1&#41;$3#",$ifcParam); $string = str_replace(array('(', ')'), array('[', ']'), $ifcParam); $string = preg_replace('`([^,\[\]]+)`', '"$1"', $string); return json_decode($string); }
J'étais loin du compte !
(j’analyse tout ça demain)
encore merci.

Re: string avec virgules et parenthèse en array

Posté : 13 juin 2019, 17:05
par Saian
Le faire avec une ou deux expressions régulières me paraissait trop compliqué. C'est pour ça que j'ai plutôt fait une expression régulière simple pour récupérer toutes les chaînes entre apostrophes et y appliquer une fonction de rappel avec preg_match_callback pour pouvoir remplacer les parenthèses avec un simple str_replace. Mon parti pris a été de remplacer les caractères gênants par des chaînes arbitraires (mais signifiantes) qui à priori ne devraient pas être présentes dans la chaîne originale, puis de restaurer ces chaînes de remplacement par leur caractère original à la fin du traitement.

Je t'ai mis le stringToArray et le arrayToString. ;)

Re: [RESOLU] string avec virgules et parenthèse en array

Posté : 14 juin 2019, 10:38
par leiopar
Bon ... ben j'ai plus qu'à comprendre tout ça (et doubler la poids du code avec des commentaires que je puisse encore comprendre dans 6 mois O:) )
Encore merci. :wink:

Re: string avec virgules et parenthèse en array

Posté : 14 juin 2019, 10:59
par leiopar
Ca à l'air de fonctioner mais j'ai des message malpolis :

Code : Tout sélectionner

Warning: array_map(): Argument #2 should be an array in B:\WWW\ifc_position\res\fonctions.php on line 34
Ca vise l'avant dernière ligne de la fonction "restoreEscaped" :

Code : Tout sélectionner

26|function restoreEscaped($array){ | ... 34| }, $array); 35|}

Re: string avec virgules et parenthèse en array

Posté : 14 juin 2019, 11:02
par leiopar
J'ai rajouté un truc qui semble filter :

Code : Tout sélectionner

function restoreEscaped($array){ //https://forum.phpfrance.com/post460425.html if(is_array($array)) return array_map(function ($entry) { return is_array($entry) ? restoreEscaped($entry) : str_replace( array(':ob:', ':cb:', ':op:', ':cp:'), array('[', ']', '(', ')'), $entry); }, $array); }