2012-01-11 26 views
10

Estoy tratando de leer un archivo .json desde un servidor web. El JSON estoy recibiendo desde el servidor se divulga para ser inválido en http://jsonlint.com/:Convertir inválido json en json válido

{ 
    preOpen: "900", 
    preClose: "908", 
    mktOpen: "915", 
    mktClose: "1530", 
    corrOpen: "1540", 
    corrClose: "1600", 
    mktStatusCode: "3", 
    status: "MARKET OPEN", 
    time: "Jan 11, 2012 12:32:14", 
    data: [ 
     { 
      name: "S&P CNX NIFTY Pre Open", 
      lastPrice: "4,863.15", 
      change: "13.60", 
      pChange: "0.28", 
      imgFileName: "S&P_CNX_NIFTY_Pre_Open_open.png" 
     }, 
     { 
      name: "S&P CNX NIFTY", 
      lastPrice: "4,871.15", 
      change: "21.60", 
      pChange: "0.45", 
      imgFileName: "S&P_CNX_NIFTY_open.png" 
     }, 
     { 
      name: "CNX NIFTY JUNIOR", 
      lastPrice: "8,940.05", 
      change: "91.90", 
      pChange: "1.04", 
      imgFileName: "CNX_NIFTY_JUNIOR_open.png" 
     }, 
     { 
      name: "BANK NIFTY", 
      lastPrice: "8,816.15", 
      change: "81.10", 
      pChange: "0.93", 
      imgFileName: "BANK_NIFTY_open.png" 
     }, 
     { 
      name: "INDIA VIX", 
      lastPrice: "24.18", 
      change: "0.18", 
      pChange: "0.75", 
      imgFileName: "INDIA_VIX_open.png" 
     }, 
     { 
      name: "CNX 100", 
      lastPrice: "4,729.25", 
      change: "25.05", 
      pChange: "0.53", 
      imgFileName: "CNX_100_open.png" 
     }, 
     { 
      name: "S&P CNX DEFTY", 
      lastPrice: "3,265.00", 
      change: "41.70", 
      pChange: "1.29", 
      imgFileName: "S&P_CNX_DEFTY_open.png" 
     }, 
     { 
      name: "S&P CNX 500", 
      lastPrice: "3,811.75", 
      change: "26.40", 
      pChange: "0.70", 
      imgFileName: "S&P_CNX_500_open.png" 
     }, 
     { 
      name: "CNX MIDCAP", 
      lastPrice: "6,548.20", 
      change: "80.65", 
      pChange: "1.25", 
      imgFileName: "CNX_MIDCAP_open.png" 
     }, 
     { 
      name: "NIFTY MIDCAP 50", 
      lastPrice: "1,937.20", 
      change: "21.30", 
      pChange: "1.11", 
      imgFileName: "NIFTY_MIDCAP_50_open.png" 
     }, 
     { 
      name: "CNX INFRA", 
      lastPrice: "2,273.60", 
      change: "8.50", 
      pChange: "0.38", 
      imgFileName: "CNX_INFRA_open.png" 
     }, 
     { 
      name: "CNX REALTY", 
      lastPrice: "207.85", 
      change: "8.10", 
      pChange: "4.06", 
      imgFileName: "CNX_REALTY_open.png" 
     }, 
     { 
      name: "CNX ENERGY", 
      lastPrice: "7,300.55", 
      change: "37.10", 
      pChange: "0.51", 
      imgFileName: "CNX_ENERGY_open.png" 
     }, 
     { 
      name: "CNX FMCG", 
      lastPrice: "10,308.90", 
      change: "10.90", 
      pChange: "0.11", 
      imgFileName: "CNX_FMCG_open.png" 
     }, 
     { 
      name: "CNX MNC", 
      lastPrice: "4,660.35", 
      change: "30.40", 
      pChange: "0.66", 
      imgFileName: "CNX_MNC_open.png" 
     }, 
     { 
      name: "CNX PHARMA", 
      lastPrice: "4,743.15", 
      change: "-4.15", 
      pChange: "-0.09", 
      imgFileName: "CNX_PHARMA_open.png" 
     }, 
     { 
      name: "CNX PSE", 
      lastPrice: "2,753.90", 
      change: "14.60", 
      pChange: "0.53", 
      imgFileName: "CNX_PSE_open.png" 
     }, 
     { 
      name: "CNX PSU BANK", 
      lastPrice: "2,847.95", 
      change: "22.80", 
      pChange: "0.81", 
      imgFileName: "CNX_PSU_BANK_open.png" 
     }, 
     { 
      name: "CNX SERVICE", 
      lastPrice: "5,933.65", 
      change: "21.65", 
      pChange: "0.37", 
      imgFileName: "CNX_SERVICE_open.png" 
     }, 
     { 
      name: "CNX IT", 
      lastPrice: "6,300.35", 
      change: "-31.40", 
      pChange: "-0.50", 
      imgFileName: "CNX_IT_open.png" 
     }, 
     { 
      name: "CNX SMALLCAP", 
      lastPrice: "2,981.80", 
      change: "49.85", 
      pChange: "1.70", 
      imgFileName: "CNX_SMALLCAP_open.png" 
     }, 
     { 
      name: "CNX 200", 
      lastPrice: "2,432.05", 
      change: "14.35", 
      pChange: "0.59", 
      imgFileName: "CNX_200_open.png" 
     }, 
     { 
      name: "CNX AUTO", 
      lastPrice: "3,497.60", 
      change: "4.05", 
      pChange: "0.12", 
      imgFileName: "CNX_AUTO_open.png" 
     }, 
     { 
      name: "CNX MEDIA", 
      lastPrice: "1,147.30", 
      change: "23.35", 
      pChange: "2.08", 
      imgFileName: "CNX_MEDIA_open.png" 
     }, 
     { 
      name: "CNX METAL", 
      lastPrice: "2,746.95", 
      change: "60.60", 
      pChange: "2.26", 
      imgFileName: "CNX_METAL_open.png" 
     } 
    ] 
} 

Su mostrando el siguiente resultado de la prueba:

Parse error on line 1: 
{ preOpen: "900",  
-----^ 
Expecting 'STRING', '}' 

¿Cómo puedo convertir a VÁLIDA JSON antes de analizarlo usando PHP?

+0

Las claves deben estar entre comillas dobles, por lo que preOpen: "900" debe ser "preOpen": "900", y así sucesivamente. No estoy seguro de cómo solucionarlo si no tiene control sobre la fuente json. Puede usar expresiones regulares: busque una sola palabra antes de los dos puntos e inclúyala entre comillas dobles. –

Respuesta

7

Todos keys (preOpen, preClose, ...) tienen que ser cadenas, por lo que necesitan comillas dobles.

{ 
    "preOpen": "900", 
    "preClose": "908", 
    ... 
} 

ACTUALIZACIÓN === ===

Si usted tiene un inválido JSON-cadena se puede convertir con el siguiente script:

$sInvalidJson = '{ 
    preOpen: "900", 
    preClose: "908" 
}'; 
$sValidJson = preg_replace("/(\n[\t ]*)([^\t ]+):/", "$1\"$2\":", $sInvalidJson); 

también ver este example.

(Este script sólo funciona con el JSON no válido se ha descrito anteriormente, ya que el patrón tiene que ser cambiado.)

ACTUALIZACIÓN === ===

$sInvalidJson = '{preOpen:"900",preClose:"908",mktOpen:"915",mktClose:"1530",corrOpen:"1540",corrClose:"1600",mktStatusCode:"3",status:"MARKET OPEN",time:"Jan 11, 2012 14:25:15",data:[{name:"S&P CNX NIFTY Pre Open",lastPrice:"4,863.15",change:"13.60",pChange:"0.28",imgFileName:"S&P_CNX_NIFTY_Pre_Open_open.png"},{name:"S&P CNX NIFTY",lastPrice:"4,847.85",change:"-1.70",pChange:"-0.04",imgFileName:"S&P_CNX_NIFTY_open.png"},{name:"CNX NIFTY JUNIOR",lastPrice:"8,917.00",change:"68.85",pChange:"0.78",imgFileName:"CNX_NIFTY_JUNIOR_open.png"},{name:"BANK NIFTY",lastPrice:"8,768.75",change:"33.70",pChange:"0.39",imgFileName:"BANK_NIFTY_open.png"},{name:"INDIA VIX",lastPrice:"24.61",change:"0.61",pChange:"2.54",imgFileName:"INDIA_VIX_open.png"},{name:"CNX 100",lastPrice:"4,707.85",change:"3.65",pChange:"0.08",imgFileName:"CNX_100_open.png"},{name:"S&P CNX DEFTY",lastPrice:"3,253.50",change:"30.20",pChange:"0.94",imgFileName:"S&P_CNX_DEFTY_open.png"},{name:"S&P CNX 500",lastPrice:"3,795.40",change:"10.05",pChange:"0.27",imgFileName:"S&P_CNX_500_open.png"},{name:"CNX MIDCAP",lastPrice:"6,524.90",change:"57.35",pChange:"0.89",imgFileName:"CNX_MIDCAP_open.png"},{name:"NIFTY MIDCAP 50",lastPrice:"1,926.55",change:"10.65",pChange:"0.56",imgFileName:"NIFTY_MIDCAP_50_open.png"},{name:"CNX INFRA",lastPrice:"2,262.05",change:"-3.05",pChange:"-0.13",imgFileName:"CNX_INFRA_open.png"},{name:"CNX REALTY",lastPrice:"207.70",change:"7.95",pChange:"3.98",imgFileName:"CNX_REALTY_open.png"},{name:"CNX ENERGY",lastPrice:"7,301.05",change:"37.60",pChange:"0.52",imgFileName:"CNX_ENERGY_open.png"},{name:"CNX FMCG",lastPrice:"10,235.35",change:"-62.65",pChange:"-0.61",imgFileName:"CNX_FMCG_open.png"},{name:"CNX MNC",lastPrice:"4,631.55",change:"1.60",pChange:"0.03",imgFileName:"CNX_MNC_open.png"},{name:"CNX PHARMA",lastPrice:"4,749.95",change:"2.65",pChange:"0.06",imgFileName:"CNX_PHARMA_open.png"},{name:"CNX PSE",lastPrice:"2,744.85",change:"5.55",pChange:"0.20",imgFileName:"CNX_PSE_open.png"},{name:"CNX PSU BANK",lastPrice:"2,841.10",change:"15.95",pChange:"0.56",imgFileName:"CNX_PSU_BANK_open.png"},{name:"CNX SERVICE",lastPrice:"5,900.60",change:"-11.40",pChange:"-0.19",imgFileName:"CNX_SERVICE_open.png"},{name:"CNX IT",lastPrice:"6,262.10",change:"-69.65",pChange:"-1.10",imgFileName:"CNX_IT_open.png"},{name:"CNX SMALLCAP",lastPrice:"2,963.90",change:"31.95",pChange:"1.09",imgFileName:"CNX_SMALLCAP_open.png"},{name:"CNX 200",lastPrice:"2,421.50",change:"3.80",pChange:"0.16",imgFileName:"CNX_200_open.png"},{name:"CNX AUTO",lastPrice:"3,484.30",change:"-9.25",pChange:"-0.26",imgFileName:"CNX_AUTO_open.png"},{name:"CNX MEDIA",lastPrice:"1,139.60",change:"15.65",pChange:"1.39",imgFileName:"CNX_MEDIA_open.png"},{name:"CNX METAL",lastPrice:"2,726.75",change:"40.40",pChange:"1.50",imgFileName:"CNX_METAL_open.png"}]}'; 
$sValidJson = preg_replace("/([{,])([a-zA-Z][^: ]+):/", "$1\"$2\":", $sInvalidJson); 

También este updated example.

+0

Muy buena respuesta. Funciona muy bien, excepto por el tiempo de la parte: "Ene 11, 2012 12:32:14", "que está jodido. – DKSan

+0

@DKSan: thx, he actualizado mi respuesta. – scessor

+0

Estoy usando el siguiente código sin éxito: '$ url = 'http: //abc/abc.json'; $ session = curl_init ($ url); curl_setopt ($ session, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: 1.8.1.13) Gecko/20080311 Firefox/2.0.0.13'); curl_setopt ($ session, CURLOPT_POST, true); curl_setopt ($ session, CURLOPT_HEADER, false); curl_setopt ($ session, CURLOPT_RETURNTRANSFER, true); $ json = curl_exec ($ session); echo $ json; echo "


"; $ sValidJson = preg_replace ("/ (\ n [\ t] *) ([^ \ t] +): /", "$ 1 \" $ 2 \ ":", $ json); echo $ sValidJson; '¡Estoy obteniendo el mismo resultado! – Sandy505

2

Creo que las cadenas JSON adecuadas también necesitan comillas dobles para todos los nombres de las teclas. Lo que se muestra es un objeto JavaScript válido, pero cuando se escribe en JSON debe tener comillas dobles alrededor de todas las teclas.

+0

Sí, al usar 'JSON.stringify (eval ({preOpen:" 900 ", ....}))', se devuelve JSON válido. @ Sandy505 Sin embargo, el uso de eval es peligroso, especialmente si los datos provienen de fuentes de terceros, ya que no se sabe qué se podría pasar. Podría ser un código malicioso inyectado en su página web. De todos modos ese no es el lado de PHP. –

0

Los nombres de propiedad deben ser citados. Ver http://json.org/example.html para un ejemplo. Cambiaría el servidor para producir JSON adecuado.

Debe estar produciendo algo así como { "preOPen": "900", .... }

0

Sí, es malformada - comillas alrededor de los nombres clave que falta. Necesita analizarlo usted mismo como una cadena ... o cambiar el archivo en el servidor.

2

La mayoría de las soluciones ofrecidas tienen una serie de problemas, principalmente con dos puntos.

Escribí una función json to array que soluciona este problema.

También comprueba si hay llaves redondas alrededor de la cadena json y las elimina pre json_decode.

Aquí es la función:

function jsonDecode($string, $assoc=true, $fixNames=true){ 
    if(strpos($string, '(') === 0){ 
    $string = substr($string, 1, strlen($string) - 2); // remove outer (and) 
    } 
    if($fixNames){ 
    $string = preg_replace("/(?<!\"|'|\w)([a-zA-Z0-9_]+?)(?!\"|'|\w)\s?:/", "\"$1\":", $string); 
    } 
    return json_decode($string, $assoc); 
} 

también comprueba si hay espacios en blanco antes de los dos puntos y los excluye de los nombres de las variables.

Aquí es una cadena de ejemplo que probé:

({estilo: "border: 5px sólido de color rosa;", clase: "test", "correcto": "valor", prueba: true, var5: "algunos escaparon \" cadena "})

Después de la conversión:.

Array 
(
    [style] => border: 5px solid pink; 
    [class] => test 
    [correct] => value 
    [test] => 1 
    [var5] => some escaped" string 
) 

Hasta ahora parece a prueba de balas

Avíseme si encuentra un agujero.