Регулярное выражение: заменить в строке вложенные элементы

#javascript

#javascript

Вопрос:

У меня есть эта строка :

 const string = "{* * @test * { * username: {{username}} * email: {{email}} * password: {{password}} * name: { * first: {{firstname}} * last: {{lastname}} * }, * phone: {{phone}} * } }"
  

и я хочу, чтобы в итоге получилось что-то вроде этого :

 {
    "username": "{{username}}",
    "email": "{{email}}",
    "password": "{{password}}",
    "name": {
        "first": "{{firstname}}",
        "last": "{{lastname}}"
    },
    "phone": "{{phone}}"
}
  

Вот мой код :

     const str = "{* * @test * { * username: {{username}} * email: {{email}} * password: {{password}} * name: { * first: {{firstname}} * last: {{lastname}} * }, * phone: {{phone}} * } }"




    const regex = /.* { * ([^:] ): ([^ ] ) * } }/gm;
    const subst = `{nt"$1": "$2"n}`;
    
    // The substituted value will be contained in the result variable
    const result = str.replace(regex, subst);
    
    console.log(result);  

Ответ №1:

Один из подходов заключается в замене всех ваших недопустимых токенов JSON для получения допустимой строки JSON и использования JSON.parse для преобразования строки JSON в объект.

Это довольно неуклюже, как показано, и, вероятно, нуждается в доработке и оптимизации, если у вас есть дополнительные крайние случаи в ваших реальных данных, но должно хорошо справиться с рекурсивной структурной проблемой. Рассматривайте это как подтверждение концепции.

 const string = "{* * @test * { * username: {{username}} * email: {{email}} * password: {{password}} * name: { * first: {{firstname}} * last: {{lastname}} * }, * phone: {{phone}} * } }";

const cleaned = string
  .replace(/({{. ?}})/g, `"$1"`)           // quote the template variables
  .replace(/ * ([a-z] ?): /ig, ` "$1": `) // quote the keys
  .replace(/" "/g, `","`)                  // add commas between keys
  .replace(/*/g, "")                      // remove asterisks
  .replace(/@[a-z] /ig, "")                // get rid of the `@test`
  .trim()                                  // trim so we can rip off the `{}`s
;

const parsed = JSON.parse(cleaned.substr(1, cleaned.length - 2));

const expected = {
    "username": "{{username}}",
    "email": "{{email}}",
    "password": "{{password}}",
    "name": {
        "first": "{{firstname}}",
        "last": "{{lastname}}"
    },
    "phone": "{{phone}}"
};

console.log(
  `matches expected? ${JSON.stringify(expected) === JSON.stringify(parsed)}n`, 
  parsed
);