使用正则表达式从字符串递归生成对象

时间:2016-07-03 23:19:18

标签: javascript regex string object recursion

在我将字符串转换为对象的努力中,我想将自己推向生成类似JSON的结构,但语法最少 基于缩进(如玉)而不是花括号和&引号。

我已接近我需要的东西,但我无法弄清楚如何使用生成的数据生成对象。

我知道我必须使用recursion来动态创建基于每行indentation的对象,或者至少是我想的那样。

我会在这里包含代码逻辑,但它在文本编辑器中更具可读性。 这是codepen

输入



project = MyApp
  files
    js = [one.js , two.js ,three.js ,coffe ,382, 90]
    scss = [pannel.scss , house.scss]
  compiled
    files = [main.js , main.css , main.html]
    opts = (type : es2015 , msg : multi line string ,online : true , isArray : probably )
  src = ./src
  dest = ./dest
  tree
    level1
      level2
        level3
          out = ./out/to/path




输出



{
  project:'MyApp',
    files:{
      js:['one.js' ,' two.js' ,'three.js'],
      scss:['pannel.scss' , 'house.scss']
    },
  compiled:{
    files:['main.js' ,'main.css','main.html'],
    opt:{type:'es2015',msg:'multi line string' , online:'true' ,isArray:'probably'}
  },
  src:'./src',
  dest:'./dest',
  tree:{
    level1:{
      level2:{
        level3:{
          out:'./output/to/path'
        }
      }
    }
  }
}




1 个答案:

答案 0 :(得分:0)

您的价值观是一种放松的JSON。在网上查看之后,我找到了一个非常适合您所需要的库(在解析值时),唯一的区别是key/value分隔符是=。因此,我更改了代码以满足您的要求,但有一些限制,请参阅[1]。关于树木建筑,我写了自己的版本。请查看代码段:



let input = `
project = MyApp
  files
    js = [one.js , two.js ,three.js ,coffe ,382, 90]
    scss = [pannel.scss , house.scss]
  compiled
    files = [main.js , main.css , main.html]
    opts = (type : es2015 , msg : "mult ilin estring" ,online : true , isArray : probably )
  src = ./src
  dest = ./dest
  tree
    level1
      level2
        level3
          out = ./out/to/path
`
let result = {};
let lines = input.split('\n').slice(1, -1);//Get lines and remove start/end space.
let cursor = result;//Keep track of current position
let path = []; //Store old psition to make it easy reach upper levels.
path.push(result);
let currentLevel = 0;

for(var i in lines) {

  let level = lines[i].search(/\S/);
  let line = lines[i].substr(level);
  
  if(level < currentLevel) {
    	path.pop();
  }
  cursor = path[path.length-1];
  currentLevel = level;
  
  if(line.indexOf('=') === -1) {
    cursor[line] = {};
    path.push(cursor[line]);
    cursor = cursor[line];
  } else {
    var parts = line.split(/\s*=\s*/);
    //Here I used the modified jsonlite
    cursor[parts[0]] = jsonlite.parse(parts[1], false);
  }
}

console.log(result);
&#13;
<script src="https://rawgit.com/iRbouh/6d2889a55794b03bb88bf15149a931d1/raw/53728a446051af8752ea15d83e27217e141a9b74/jsonlite.js"></script>
&#13;
&#13;
&#13;

[1]:对象键,字符串值,数字值,true,false,值的值都可以没有引号,只要它们不包含特殊字符:空格(\t\n ...),双引号("),逗号(,),方括号([,]),对象开始和结束( {}(),具体取决于选项),配对分隔符(:)。