Парсинг sql условного выражения в массив

96
19 октября 2019, 03:30

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

let str='(`id`=3) and (`filter`=\'test\' or (`filter`=\'1\' and `name`=\'2\'))'

Мне нужно чтобы строка превратилась в такой массив

let arr=[['id','=', '3'], 'and', [['filter','=', 'test'],
                                  'or', 
                                  [['filter','=', '1'],
                                   'and',
                                   ['name', '=', 'i']]]]

Я сделал это

  let str = "((`id`=3) and (`filter`='te\\\'st' or (`filter`='1' and `name`='2')))";
  let expression = [];
  let i = 0;
  let level = 0;
  let result = matches(str, /'(\\.|[^'])*'/ig, i, 't');
  let text = result.text;
  let phrase = parseSQL(result.result, level, expression);
  console.log({phrase, text, expression});
  console.log(getArray(expression));
  function parseSQL(str, level, expression) {
    let j = 0;
    let result = matches(str, /\([^()]+\)/gi, j, `e${level}_`);
    let phrase = result.result;
    expression.push(result.text);
    if (result.result.match(/\(/)) {
      phrase = parseSQL(result.result, level + 1, expression);
    }
    return phrase;
  }
  function matches(str, regex, i, letter) {
    let result = str.replace(regex, function () {
      return `$${letter}${i++}`;
    });
    let text = str.match(regex);
    return {result, text};
  }

У меня есть массив в котором есть ключи с уровнем, по которым я смогу собрать нужный вложенный массив, только не могу придумать как это сделать

Answer 1

Теперь работает как нужно, вдруг кому понадобиться

  let str = "((`id`='3') and (`filter`='te\\\'st' or (`filter`='1' and `name`='2')))";
  let expression = [];
  let i = 0;
  let level = 0;
  let result = getMatches(str, /'(\\.|[^'])*'/ig, i, 't');
  let text = result.text;
  let phrase = encryptExpression(result.result, level, expression);
  console.log({phrase, text, expression});
  let position = phrase.match(/\$e(\d)_(\d)/);
  let newArr = expression[position[1]][position[2]];
  newArr = getArray(expression, text, position, newArr);
  newArr = compareValues(newArr);
  console.log(newArr);
  function encryptExpression(str, level, expression) {
    let j = 0;
    let result = getMatches(str, /\([^()]+\)/gi, j, `e${level}_`);
    let phrase = result.result;
    expression.push(result.text);
    if (result.result.match(/\(/)) {
      phrase = encryptExpression(result.result, level + 1, expression);
    }
    return phrase;
  }
  function getMatches(str, regex, i, letter) {
    let result = str.replace(regex, function () {
      return `$${letter}${i++}`;
    });
    let text = str.match(regex);
    return {result, text};
  }
  function getArray(expression, text, position, newArr) {
    if (newArr.match(/([^(]+)\s+(and|or|not)\s+([^)]+)/i)) {
      newArr = newArr.match(/([^(]+)\s+(and|or|not)\s+([^)]+)/i).slice(1);
      for (let i = 0; i < newArr.length; i++) {
        if (newArr[i].match(/\$e(\d)_(\d)/)) {
          position = newArr[i].match(/\$e(\d)_(\d)/);
          if (expression[position[1]][position[2]].charAt(0) === '('
            && expression[position[1]][position[2]].charAt(expression[position[1]][position[2]].length - 1) === ')') {
            newArr[i] = expression[position[1]][position[2]].substring(1, expression[position[1]][position[2]].length - 1)
          }
        }
        newArr[i] = getArray(expression, text, position, newArr[i]);
        if (typeof(newArr[i]) !== 'object') {
          if (newArr[i].match(/`(.*)`\s*(=|>|<|>=|<=|like|!=)\s*(\$t\d+)/i)) {
            newArr[i] = newArr[i].match(/`(.*)`\s*(=|>|<|>=|<=|like|!=)\s*(\$t\d+)/i).slice(1);
          }
        }
      }
    }
    return newArr;
  }
  function compareValues(newArr) {
    if (newArr instanceof Array) {
      for (let i = 0; i < newArr.length; i++) {
        if (!(newArr[i] instanceof Array)) {
          if (newArr[i].match(/\$t(\d+)/)) {
            newArr[i] = text[newArr[i].match(/\$t(\d+)/)[1]];
          }
        }
        newArr[i] = compareValues(newArr[i]);
      }
    }
    return newArr;
  }
READ ALSO
Анимация polylines google maps

Анимация polylines google maps

стоит задача на гугл карте сделать анимацию полета самолетовКак сделать анимацию из одной точки во вторую я знаю:

153
Цепочка прототипов и hasOwnProperty

Цепочка прототипов и hasOwnProperty

Не могу понятьНа MDN пишут, что:

84
Jquery отказывается работать

Jquery отказывается работать

Вот есть код в чате с формой и отправкой аякс запроса по нажатию на кнопкуНО увы ничего не происходит

120
Почему нету данных на сервере express

Почему нету данных на сервере express

Имеется код для отправки формы

91