Замените переменную строку регулярным выражением nodejs - PullRequest
0 голосов
/ 02 апреля 2019

Мне нужно идентифицировать шаблоны, подобные приведенным ниже, внутри очень большой строки и заменить их на «null»:

["pmeta", ["ImageSelectStoreFront", null, 3, 4, 2, null, "Storefront", []]], ["pmeta", ["/m/01pns0", null, 3, 3, 3, null, "fire hydrant", []], null, [1]], ["pmeta", ["/m/0199g", null, 3, 3, 3, null, "bicycle", []], null, [1]],

Эти строки выглядят как JSON, ноСтрока, в которой они отображаются, не является JSON, поэтому нет смысла ее анализировать.Мне также не нужно анализировать этот JSON, мне нужно удалить его из строки, в которой он появляется.

Единственными частями, которые всегда одинаковы, являются ["pmeta",, закрывающая скобка и запятая наконец.

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

Может кто-нибудь дать мне несколько указателей на регулярные выражения или предложитьдругие способы сделать это?

Ответы [ 2 ]

1 голос
/ 02 апреля 2019

Вместо регулярного выражения вы можете выполнить пользовательский анализ. Работает следующим образом:

  1. Найти, есть ли что-нибудь, что начинается с ["pmeta" на входе.
  2. Считайте, что startIndex
  3. Найти индекс последней закрывающей скобки после этого индекса, сохранив стопку скобок. Вы добавляете один элемент в стек для каждой открытой скобки, удаляете элемент для любой закрывающей скобки. Когда вы очищаете стек, это последняя закрывающая скобка. Считайте это как endIndex
  4. Найдите секцию строки от startIndex до endIndex и затем замените ее на null.

Я сократил (и анонимно) ваш образец, заменив длинные значения на отдельные слова:

let input = `)]}'
["rresp",
"one",
null,
120,
["pmeta",["/m/01pns0",null,3,3,3,null,"fire hydrant",[]
]
,null,[1]
]
,"dynamic",null,["bgdata","two","","three"]
,"four","five"]`

let output = clean(input);
console.log("output", output);

function clean(text) {
  let startIndex = text.indexOf('["pmeta"');

  //nothing to remove - early exit
  if (startIndex === -1) return text; 

  let endIndex = findLastOpenBracket(text, startIndex);
  
  let toReplace = text.substring(startIndex, endIndex);
  console.log("found text to replace:", toReplace);
  
  return text.replace(toReplace, "null")
}

function findLastOpenBracket(text, startIndex) {
  let openBrackets = [];
  
  for (let i = startIndex; i < text.length; i++) {
    let char = text[i];
    if (char === "[") {
      openBrackets.push(char);
    } else if (char === "]") {
      openBrackets.pop()
      
      if(openBrackets.length === 0){
        return i + 1
      }
    }
  }
}

Предполагается, что будет закрывающей скобкой, заканчивающей последовательность. Следует признать, что функцию findLastOpenBracket можно значительно улучшить, но я не знаю требований здесь, и она соответствует образцу данных. По крайней мере, это один алгоритм, который можно заменить, остальные шаги остаются согласованными.

Еще одно примечание: шаг 4. немного громоздкий. К сожалению, в JavaScript нет метода .splice для строк, поэтому вам нужно пройти длинный путь - получить подстроку -> заменить подстроку в строке. Вместо этого вы можете использовать метод Array.splice(), если это необходимо, но я также считаю его громоздким:

let text = "one,two,three";

//replace "two"
let startIndex = 4;
let endIndex = 7;


let arr = text.split("");
arr.splice(
  startIndex, 
  endIndex - startIndex, 
  "null"
)

let output = arr.join("");
console.log(output);
0 голосов
/ 02 апреля 2019

Предполагается, что в строке есть только одно вхождение шаблона, и что нет других вхождений ],, тогда \["pmeta",.*\], может сработать.Regex demo: https://regex101.com/r/4DSfVR/1

Реализация JavaScript:

inputstr = 'djfhjkdfhkhdf ["pmeta", ["ImageSelectStoreFront", null, 3, 4, 2, null, "Storefront", []]],jdkfhkjdhf';
pattern = new RegExp('\\["pmeta",.*\\],',"gm");
console.log(inputstr.replace(pattern,""));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...