javascript - regex - соответствует «родительское» отношение повторяющихся тегов - PullRequest
1 голос
/ 27 июня 2019

У меня есть этот текст

parent( child( child_of_child(value)  ) )

и этот шаблон регулярных выражений для математики с

([a-z]+\(.*\))

Я использую JavaScript-код

'parent( child( child_of_child(value)  ) )'.match(/([a-z]+\(.*\))/g)

текущий результат:

["parent( child( child_of_child(value)  ) )"]

ожидаемый результат:

parent: {
     m: 'parent( child( child_of_child(value)  ) )',
     child: {
        m: 'child( child_of_child(value)  )',
        child: {
            m: 'child_of_child(value)'
        }
     }
}

Любая помощь направления будет очень приветствоваться

Ответы [ 3 ]

1 голос
/ 27 июня 2019

Вы можете использовать рекурсивную функцию и шаблон с 4 группами захвата, в которых вы можете найти соответствие от открывающей до закрывающей скобки.

Затем проверьте в следующей итерации проверку, соответствует ли шаблон по-прежнему.В следующем вызове используйте группы для создания объекта с ключом и значениями.

([^()]+)(\()(.*)(\))
  • ([^()]+) Группа 1, захват 1+ раз, а не ( или )
  • (\() Группа 2, захват (
  • (.*) Группа 3, захват любого символа 0+ раз, кроме новой строки
  • (\)) Группа 4, захват )

Regex demo

let pattern = /([^()]+)(\()(.*)(\))/;
let string = "parent( child( child_of_child(value)  ) )";

function parse(str, obj) {
  if (pattern.test(str)) {
    let res = str.match(pattern);
    res.shift();
    parse(res[2], obj[res[0]] = {
      'm': res.join('')
    });
  }
  return obj;
}

console.log(JSON.stringify(parse(string, {}), null, 2));
1 голос
/ 27 июня 2019

Попробуйте использовать это регулярное выражение вместо

let regexp = /([a-z]+)(\(.*\))/;
let text = 'parent( child( child_of_child(value)  ) )';
let match = text.match(regex);

Будет производить

0: "parent( child( child_of_child(value)  ) )"
1: "parent"
2: "( child( child_of_child(value)  ) )"

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

Это не совсем тот вывод, который вам нужен, но преобразование будет действительно простым.

0 голосов
/ 27 июня 2019

Благодаря направлению Фарвилайн я нашел решение для этого.

регулярное выражение изменено на:

/([a-z\_]+)\((.*)\)/

и вместо "соответствия" я использовал "заменить"

и вот оно:

var explore_parent_child = (val, reg) => {
var v = val.replace(reg, (a, b, c) => {

    var res = {};
    var exp = explore_parent_child(c, reg);
    if(typeof(exp) == 'object') {
        exp.m = a;
        res[b] = exp;
    } else{
        res[b] = {
            m: a,
            child: exp
        };
    }

    return JSON.stringify(res);
})

try { return JSON.parse(v) } catch { return v };}

пример выполнения:

explore_parent_child("parent( child( child_of_child(value)  ) )", /([a-z\_]+)\((.*)\)/)

результат:

parent: {
 m: 'parent( child( child_of_child(value)  ) )',
 child: {
    m: 'child( child_of_child(value)  )',
    child_of_child: {
        m: 'child_of_child(value)',
        value: 'value'
    }
 } }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...