将点表示法转换为JSON

时间:2012-06-19 21:32:24

标签: javascript json

我有一堆形式的字符串:“AAA.BBB [0] .CCC.DDD [5] .EEE = 123”。有些甚至包含更深层次的嵌套数组。如何将该点符号转换为等效的JSON对象?我正在使用jQuery,如果它提供任何额外的优势。我已经找到了几乎可以做到这一点的方法,但是当包含数组时没有解决方案。

编辑: 我需要为许多字符串执行此操作并最终将它们组合在一起。特别是这个应该成为表单的对象(假设我没有出现任何错误): {“AAA”:{“BBB”:[“CCC:{”DDD“:[{},{},{},{},{},{”EEE“:123}]}]}

2 个答案:

答案 0 :(得分:3)

您所描述的不是只是转换为JSON的东西。你所描述的是对象的层次结构,当然,但是那里有那些括号,你显然只是看着一块更大的物体。但是,对于解析器将该字符串转换为javascript对象,我们可以这样做:

function splitStringToObject(string){
  var sourceArray = string.split('.');
  var top = {};
  var point = top;
  while (sourceArray.length){
    var work = sourceArray.shift();
    if ( /([a-zA-Z_][a-zA-Z0-9_]*)\[([a-zA-Z0-9_]+)\]/.test(work) ){
      console.log('found match alpha index')
      //found an array identifier with a variable name inside ('bbb[aaa]')
      var matches = /([a-zA-Z_][a-zA-Z0-9_]*)\[([a-zA-Z0-9_]+)\]/.exec(work);
      var matchName = matches[1];
      var matchIndex = matches[2];
      point[matchName] = [];
      point[matchName][matchIndex] = {};
      point = point[matchName][matchIndex];
    } else if ( /([a-zA-Z_][a-zA-Z0-9_]*)\[([0-9]+)\]/.test(work) ) {
      console.log('found match numeric index')
      //found an array identifier with a numeric index inside ('bbb[0]')
      var matches = /([a-zA-Z_][a-zA-Z0-9_]*)\[([a-zA-Z0-9_]+)\]/.exec(work);
      var matchName = matches[1];
      var matchIndex = matches[2];
      point[matchName] = [];
      point[matchName][matchIndex] = {};
      point = point[matchName][matchIndex];
    } else if ( work.indexOf('[') > -1 || work.indexOf(']') > -1 ) {
      console.log('found bad egg with ' + work)
    } else if ( work.indexOf('=') > 0 ) { 
      console.log('found = inside')
      //test for equals sign in the string
      var morework = work.split('=');
      work = morework[0].trim();
      sourceArray.push('='+morework[1])
      point[work] = morework[1].trim();
      point = point[work];
    } else { 
      console.log('found plain word')
      //assume work is aok to use as another object here.
      work = work.trim();
      point[work] = {};
      point = point[work];
    }
  }
  //you may not want this next part
  var ret;
  //let's pull our value off the top, altho if we do this, I don't know
  //how to retain the name. I prefer to return it under top still
  for (var k in top){
    ret = top[k];
  }

  console.log(ret);
  return ret;

  // alternately call
  return top;
}

但是,这只是一个解析器,我们如何使用它?好吧,我们需要提供我们的字符串。我假设你可以把所有的字符串整齐地放到一个数组中,如下所示:

var strings = [
  "AAA.BBB[0].CCC.DDD[1].EEE = 123",
  "AAA.BBB[0].CCC.DDD[2].EEE = 123",
  "AAA.BBB[0].CCC.DDD[4].EEE = 123",
  "AAA.BBB[0].CCC.DDD[5].EEE = 123",
];

然后下一部分变得非常简单,正如我们在这里看到的那样:

var objectsConverted = [];
for(var k in strings){
  objectsConverted[k] = splitStringToObject(strings[k]);
}

var result = {};
for(var k in objectsConverted){
  jQuery.extend(true,result,objectsConverted[k]);
}

console.log(result);

并且在一天结束时如果我JSON.stringify(结果)我得到:

"{"BBB":[{"CCC":{"DDD":[null,{"EEE":"123"},{"EEE":"123"},null,{"EEE":"123"},{"EEE":"123"}]}}]}"

请阅读函数末尾内部的警告,由于返回方法的选择,命名空间丢失(我从顶部返回而不是嵌套一次)

答案 1 :(得分:0)

AAA.BBB[0].CCC.DDD[5].EEE

变为:

{AAA : {
  BBB : [{ 
   CCC: {
    DDD: [ 
...

如果您有成员X[Y],则只需将其转换为将X映射到元素数组的对象。

这有帮助吗?