Регулярное выражение между тегами, если не сбежать

Я создал оболочку PHP вокруг библиотеки Pygments, которая выделяет блоки кода. Регулярное выражение, используемое для обнаружения кодовых блоков, может быть сконфигурировано в файле конфигурации . (формат json)

Это похоже на значение json:

{ "codeblock_regex": "\\[pygments=(.*?)\\](.*?)\\[\\/pygments\\]" } 

Который должен выглядеть так после того, как он был декодирован JSON:

 \[pygments=(.*?)\](.*?)\[\/pygments\] 

Это плохо, так как он не позволяет ускользнуть, я хочу, чтобы люди могли это сделать:

 \[pygments=lexer]some code here[/pygments] 

И пигменты для обнаружения \ и просто игнорировать этот блок кода. Я попытался с

  "(^\\\\)\\[pygments=(.*?)\\](.*?)\\[\\/pygments\\]" 

который должен выглядеть так после json_decode :

  (^\\)\[pygments=(.*?)\](.*?)\[\/pygments\] 

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

То, что вам нужно, – довольно сложная функция регулярного выражения, называемая «отрицательным утверждением с нулевой шириной» . «Zero-width» означает, что он соответствует нулевым символам ввода, «отрицательный» означает, что он преуспевает, только если он не найден, а «look-behind» означает, что он смотрит назад.

Синтаксис для этого – (?<!test) где test – это то, чего вы хотите, чтобы этого не было.

В вашем случае вы хотите сопоставить [ но игнорировать его, если ему предшествует символ \ , оба из которых требуют экранирования, поэтому вам нужно (?<!\\)\[

Итак, ваше регулярное выражение заканчивается как (в PHP) $re = '/(?<!\\\\)\[pygments=(.*?)\](.*?)\[\/pygments\]/';

Согласно json_encode , это заканчивается как "\/(?<!\\\\)\\[pygments=(.*?)\\](.*?)\\[\\\/pygments\\]\/" в JSON. Я думаю, что мои глаза начинают смеяться со всеми обратными косыми чертами … ;)