JS Regex, чтобы соответствовать всем внутри фигурных скобок (включая вложенные фигурные скобки): "{Я хочу, чтобы это {и это}, и это в одной строке}

Смысл в том, что я просто хочу снять прилагаемые фигурные скобки. Я могу сопоставить "{this type stuff}" с:

"{stuff}".match(/{([^}]*)}/)[1]

Я слишком много спрашиваю здесь?

Другой пример: у меня этот код javascript как строка:

{
    var foo = {
        bar: 1    
    };

    var foo2 = {
        bar: 2    
    };
}

Я хочу снять только внешние фигурные скобки:

var foo = {
    bar: 1
};

var foo2 = {
    bar: 2
}

Ответ 1

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

Проблема в том, что вы сопоставляете все, кроме }. Но поскольку внутренние данные, которые вы хотите сопоставить, содержат сам }, содержимое внешних фигурных скобок не соответствует.

{
    var foo = {
        bar: 1
==> };

    var foo2 = {
        bar: 2    
==> };
}

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

{([\S\s]*)}

Объяснить:

{                   match opening {
    (               group
        [\S\s]      match everything, workaround for the missing s option in JS
              *     greedy, makes it match as much as possible
    )               end group
}                   match closing }

Ответ 2

Попробуйте это (я основываю свой код на на этом ответе). Он также знает, что игнорировать скобки в строках и комментариях (однострочные и многострочные) - как отмечено в разделе комментариев этого ответа:

var block = /* code block */
    startIndex = /* index of first bracket */,
    currPos = startIndex,
    openBrackets = 0,
    stillSearching = true,
    waitForChar = false;

while (stillSearching && currPos <= block.length) {
  var currChar = block.charAt(currPos);

  if (!waitForChar) {
    switch (currChar) {
      case '{':
        openBrackets++; 
        break;
      case '}':
        openBrackets--;
        break;
      case '"':
      case "'":
        waitForChar = currChar;
        break;
      case '/':
        var nextChar = block.charAt(currPos + 1);
        if (nextChar === '/') {
          waitForChar = '\n';
        } else if (nextChar === '*') {
          waitForChar = '*/';
        }
    }
  } else {
    if (currChar === waitForChar) {
      if (waitForChar === '"' || waitForChar === "'") {
        block.charAt(currPos - 1) !== '\\' && (waitForChar = false);
      } else {
        waitForChar = false;
      }
    } else if (currChar === '*') {
      block.charAt(currPos + 1) === '/' && (waitForChar = false);
    }
  }

  currPos++ 
  if (openBrackets === 0) { stillSearching = false; } 
}

console.log(block.substring(startIndex , currPos)); // contents of the outermost brackets incl. everything inside

Ответ 3

Режимы не созданы для этого, и только несколько диалектов (PCRE и .NET Regex) могут справиться с рекурсивными структурами - JS-регулярное выражение не может.

Итак, да, вы слишком много просите. Вместо этого используйте парсер JSON.