2009-08-28 8 views
0

J'ai une chaîne qui ressemble à ceci:Quel genre de notation est-ce?

[{text:"key 1",value:"value 1"},{text:"key 2",value:"value 2"},{text:"key 3",value:"value 3"}] 

Je ne sais pas quel genre de notation est ce, autant que je sache cela est généré par un back-end ASP .NET. Cela ressemble beaucoup à JSON mais appeler json_decode() échoue.

Quelqu'un peut-il m'apporter de la lumière sur ce genre de notation et me fournir un moyen efficace de l'analyser en un ensemble clé/valeur avec PHP?

Répondre

2

De toute façon vous pouvez changer la sortie? La citation des noms de clés semble lui permettre d'analyser normalement:

$test = '[{"text":"key 1","value":"value 1"},{"text":"key 2","value":"value 2"},{"text":"key 3","value":"value 3"}]'; 

    var_dump(json_decode($test)); 
+0

Je suppose que je pourrais str_replace le texte: et la valeur: et les entourer de guillemets doubles. –

0

Il ressemble à la syntaxe javascript (similaire à JSON). Les expressions régulières sont la façon de procéder pour l'analyser. Dénuder les '[' et ']', puis séparer les ','. Puis analyser chaque objet individuellement.

+2

Le problème se pose lorsqu'une chaîne contient une virgule. – giorgian

+0

Séparez-vous sur}, {comme je le souligne ci-dessous dans ma réponse. –

+0

Les expressions régulières peuvent gérer des chaînes entre guillemets contenant des virgules. Je l'ai fait plusieurs fois. –

2

Il ressemble à JSON, mais apparemment pas exactement à la spécification. La fonction PHP json_decode aime seulement guillemets doubles noms clés:

// the following strings are valid JavaScript but not valid JSON 

// the name and value must be enclosed in double quotes 
// single quotes are not valid 
$bad_json = "{ 'bar': 'baz' }"; 
json_decode($bad_json); // null 

// the name must be enclosed in double quotes 
$bad_json = '{ bar: "baz" }'; 
json_decode($bad_json); // null 

// trailing commas are not allowed 
$bad_json = '{ bar: "baz", }'; 
json_decode($bad_json); // null 
-2

Je n'ai jamais utilisé, mais peut-être donner un coup d'œil à json_decode.

+2

avez-vous * lu * la question? – nickf

+0

ça alors, vous avez raison. Je pense que je ne devrais pas essayer de répondre aux questions à cette heure. – giorgian

0

Cela ressemble à un format personnalisé. Remplacez les délimiteurs [{et}] au début et à la fin. Puis exploser sur « }, { » et vous obtenez ceci:

text:"key 1",value:"value 1" 
text:"key 2",value:"value 2" 
text:"key 3",value:"value 3" 

À ce moment-là, vous pouvez itérer sur chaque élément du tableau et utiliser preg_match pour extraire vos valeurs.

+2

Techniquement, il n'y a pas de raison qu'une chaîne ne puisse pas contenir '}, {' ... même si c'est beaucoup moins probable qu'une chaîne contenant un ',' –

+0

La raison pour laquelle j'ai choisi d'exploser}, {est parce que, définitivement apparaît dans l'exemple de sortie en tant que délimiteur entre les valeurs d'un bloc de champ. Mais oui je suis d'accord. –

0

Cela ressemble presque à une sorte de conteneur de données de style tableau - le texte étant l'indice et la valeur étant la valeur.

$string = ....; 
$endArray = array() 
$string = trim($string,'[]'); 
$startArray = preg_split('/{.+}/'); 
// Array of {text:"key 1",value:"value 1"}, this will also skip empty conainers 
foreach($startArray as $arrayItem) { 
    $tmpString = trim($arrayItem,'{}'); // $tmp = text:"key 1",value:"value 1" 
    $tmpArray = explode(',',$tmpString); // $tmpArray = ('text: "key 1"', 'value: "value 1"') 
$endArray[substr($tmpArray[0],7,strlen($tmpArray[0])-1)] = substr($tmpArray[1],7,strlen($tmpArray[1])-1); 
} 
0

Pour obtenir vos données JSON acceptées par json_decode(), vous pouvez utiliser l'expression régulière suivante:

function json_replacer($match) { 
    if ($match[0] == '"' || $match[0] == "'") { 
    return $match; 
    } 
    else { 
    return '"'.$match.'"'; 
    } 
} 

$json_re = <<<'END' 
/" (?: \\. | [^\\"])* "  # double-quoted string, with escapes 
| ' (?: \\. | [^\\'])* '  # single-quoted string, with escapes 
| \b [A-Za-z_] \w* (?=\s*:) # A single word followed by a colon 
/x 
END; 

$json = preg_replace_callback($json_re, 'json_replacer', $json); 

Parce que les matchs ne seront jamais se chevaucher, un mot suivi par deux points dans une chaîne ne correspondra jamais.


J'ai aussi trouvé une comparaison entre les différentes implémentations de JSON pour PHP:

http://gggeek.altervista.org/sw/article_20061113.html

2

Cet échantillon est valable YAML, qui est une surcouche de JSON. Il semble y avoir at least 3 PHP libraries pour YAML. Si c'est en fait YAML, il vaut mieux utiliser une vraie librairie YAML que de l'exécuter dans une regex et de la lancer dans votre bibliothèque JSON. YAML prend en charge d'autres fonctionnalités (en plus des chaînes sans guillemets) qui, si votre backend ASP.NET utilise, ne survivront pas au voyage.

Questions connexes