замена JavaScript для таких конструкций, как {... {..} ...} - PullRequest
0 голосов
/ 06 декабря 2010

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

{...}, {... {..}...} и {...{..{..}...}..{..}...}, где ... означает любой текст, который не имеет символов '{' или '}'

Если я сделаю это:

   txt.replace(/\{[\s\S]+?}/g, function(s){return "_"+s+"_";})

, первый } будет считаться конечным совпадением, поэтому { { } } станет _{ { }_ }

Я хочурегулярное выражение, чтобы преобразовать это в _{ { } }_

PS: часть function(s) не из реального кода, например,
PPS: я хочу сделать это с регулярным выражением, если это возможно.
PPPS: Максимальный уровень скобок '{', включенных в текст, ограничен 3 или 4, обычно

ОБНОВЛЕНИЕ: Спасибо за комментарии, Давайте ограничим количество вложенных скобок до 3. Итак:

{ { { .. } .. { .. } } .. { .. } }

Ответы [ 2 ]

2 голосов
/ 06 декабря 2010

Спасибо за комментарии. Давайте ограничим количество вложенных скобок 3.

ОК, это дает то, что мы можем делать с регулярными выражениями. (Существуют такие вещи, как «расширенные» регулярные выражения, такие как найденные в Perl или Python, которые могут соответствовать произвольным вложенным скобкам, используя что-то, называемое «обратными ссылками». Я не знаю, является ли Javascript регулярным выражения "поддержите тех, хотя.)

Мы строим регулярное выражение по частям.

Сначала давайте выясним, как выглядит фрагмент с вложенными фигурными скобками без :

[^{}]*

ОК, это было легко. Любое количество не фигурных символов. :)

Конструкция с одним уровнем скобок, таким образом, выглядит как

{[^{}]*}

, поскольку нам нужны скобки в начале и в конце, и больше нигде.

Как насчет двух уровней?

Что ж, тогда у нас все еще есть скобки в начале и в конце, и нашим контентом может быть «любое количество порций данных, каждый из которых имеет либо 0, либо 1 уровень скобок».

Итак, мы собираем «0 или 1 уровней скобок», соединяя эти два выражения с | (чтобы мы соответствовали одному или другому), и ставим круглые скобки вокруг этого (потому что мы хотим рассматривать это как целый блок) и * после этого для обозначения «любого числа этой вещи, которое мы только что определили в скобках». Затем брекеты обойти все это. Это дает:

{({[^{}]*}|[^{}]*)*}
  ^^^^^^^^ ^^^^^^
exp. for   exp. for
1 level    0 levels

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

2 голосов
/ 06 декабря 2010

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

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

/{([^{}]*{[^{}]*})*[^{}]*}/

будет сопоставляться с одним уровнем вложенных фигурных скобок, и это должно быть (относительно) просто, чтобы расширить его до количества уровней вложенности, которое вам требуется.

...