Как я могу проанализировать данные в виде вложенных фигурных скобок {} с дублированными именами? - PullRequest
0 голосов
/ 24 сентября 2019

Я пытаюсь разобрать следующую строку

EOB {
   PROCEDURE { /* #1  */
      PROCEDURE_LINE="1"
      ELIGIBLE="002750"
      DEDUCTIBLE="00000"
   }
   PROCEDURE { /* #2  */
      PROCEDURE_LINE="2"
      ELIGIBLE="008725"
      DEDUCTIBLE="00000"
   }
   PROCEDURE { /* #3  */
      PROCEDURE_LINE="3"
      ELIGIBLE="010760"
      DEDUCTIBLE="00000"
   }
   PROCEDURE { /* #4  */
      PROCEDURE_LINE="4"
      ELIGIBLE="021720"
   }
   EMBEDDED_TRANSACTION {
      PROCEDURE { /* #1  */
         PROCEDURE_LINE="1"
         ELIGIBLE="002750"
         DEDUCTIBLE="00000"
      }
      PROCEDURE { /* #2  */
         PROCEDURE_LINE="2"
         ELIGIBLE="008725"
         DEDUCTIBLE="00000"
      }
      PROCEDURE { /* #3  */
         PROCEDURE_LINE="3"
         ELIGIBLE="010760"
         DEDUCTIBLE="00000"
      }
      PROCEDURE { /* #4  */
         PROCEDURE_LINE="4"
         ELIGIBLE="021720"
         DEDUCTIBLE="00000"
      }
   }
}

Желаемый вывод (объект Javascript)

{
    EOB: {
        PROCEDURE: [
            {
                PROCEDURE_LINE="1",
                ELIGIBLE="002750",
                DEDUCTIBLE="00000"
            } ... (other procedures)
        ],
        EMBEDDED_TRANSACTION: [
            {
                PROCEDURE_LINE="1",
                ELIGIBLE="002750",
                DEDUCTIBLE="00000"
            } ,,, (other procedures)
        ]
    }
}

Вот что я пробовал

let data = `EOB {
   PROCEDURE { /* #1  */
  PROCEDURE_LINE="1"
  ELIGIBLE="002750"
  DEDUCTIBLE="00000"
   }
   PROCEDURE { /* #2  */
  PROCEDURE_LINE="2"
  ELIGIBLE="008725"
  DEDUCTIBLE="00000"
   }
   PROCEDURE { /* #3  */
  PROCEDURE_LINE="3"
  ELIGIBLE="010760"
  DEDUCTIBLE="00000"
   }
   PROCEDURE { /* #4  */
  PROCEDURE_LINE="4"
  ELIGIBLE="021720"
   }
   EMBEDDED_TRANSACTION {
  PROCEDURE { /* #1  */
     PROCEDURE_LINE="1"
     ELIGIBLE="002750"
     DEDUCTIBLE="00000"
  }
  PROCEDURE { /* #2  */
     PROCEDURE_LINE="2"
     ELIGIBLE="008725"
     DEDUCTIBLE="00000"
  }
  PROCEDURE { /* #3  */
     PROCEDURE_LINE="3"
     ELIGIBLE="010760"
     DEDUCTIBLE="00000"
  }
  PROCEDURE { /* #4  */
     PROCEDURE_LINE="4"
     ELIGIBLE="021720"
     DEDUCTIBLE="00000"
  }
   }
}`

  let output =  data.replace(/\/\*.+/g, '')
                    .replace(/(.*)(\{)/g, '[$1]\n')
                    .replace(/'*.}/, '')
                    .replace(/}/g, '')
                    .replace(/^\s*\n/gm, "")
                    .replace(/.*?(?==)/g, s => s.toLowerCase())
                    .replace(/\s+"/g, '"');

console.log(output)

1 Ответ

1 голос
/ 27 сентября 2019

Вам придется создать свой собственный парсер.Это похоже на частичный JSON, но с аспектами XML (дублированные имена).Вроде как JSONXML-ISH.;) Во всяком случае, я принял вызов и придумал что-то, чтобы вы начали (так как я использую только те данные, которые вы опубликовали).Вы можете изменить это в соответствии со своими потребностями:

function parse(data) {
  var parts = data.match(/\/\*.*?\*\/|{|}|=|".*?"|[a-zA-Z_]+/g); // get only the data parts we want
  var root = {}, o = root, stack = [], name, prop;
  function readValue(s) { return +s || (s[0]=='"' ? s.substring(1, s.length-1) : s); } // read as number, string, or other
  parts.forEach((v, i) => {
     if (!v) return; // skip whitespace
     else if (v.substr(0,2) == '/*') return; // skip comment blocks
     else if (v == '{' && name) { 
        stack.push(o); // get ready to move up a level
        // ... first check of there is already a property here and convert it to an array if so ...
        if (!(name in o)) 
           o = o[name] = {}; // first time we assume no array
        else { // (else there are duplicates with the same name; add as an array instead)
           if (!o[name].length) o[name] = [o[name]]; // if not already an array convert it into one first
           o[name].push(o = {}); // add new object (o is the current object being updated)
        }
        name = ''; // reset
     }
     else if (v == '}') o = stack.pop(); // pop prevfious object from stack
     else if (v == '=') prop = true; // get ready to read a propery value next!
     else if (prop && name) { o[name] = readValue(v); name = ''; prop = false; } // have name and in prop mode, set value and reset
     else name = v; // this can only be a property name, as all other conditions were handled
  });
  return root;
}

Использование: parse(s); где s - ваша строка, конечно.;)

Обратите внимание, что это создает массивы только тогда, когда имена дублируются.Вы можете легко изменить его, чтобы всегда создавать массив на каждом вложенном уровне.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...