Что было бы регулярным выражением для замены/удаления END, где ему не предшествовал непрерывный START?

Что было бы регулярным выражением (PHP) для замены/удаления (с помощью preg_replace()) END, где ему не предшествовал unended START?

Вот несколько примеров, чтобы изобразить, что я имею в виду:

Пример 1:

Вход:

sometext....END

Выход:

sometext.... //because theres no START, therefore no need for the excess END

Пример 2:

Вход:

STARTsometext....END

Выход:

STARTsometext....END //because its preceded by a START

Пример 3:

Вход:

STARTsometext....END.......END

Выход:

STARTsometext....END....... //because the END is not preceded by a START

Надеюсь, кто-то может помочь?

Спасибо.

Ответ 1

Предполагая, что вы не ищете вложенные пары, существует простое решение для устранения избыточных END. Рассмотрим:

$str = preg_replace("/END|(START.*?END)/", "$1", $str);

Это небольшая замена назад, но имеет смысл, если вы понимаете порядок работы двигателя. Во-первых, регулярное выражение состоит из двух основных частей: END|(). Альтернативы проверяются слева направо, поэтому, если движок видит END во входной строке, он будет соответствовать ему и переходить к следующему совпадению (то есть снова искать END).
Вторая часть - группа захвата, которая содержит START.*?END - это будет соответствовать, по возможности, целым маркером Start/End. Все остальное будет пропущено, пока не найдет другой END или START.

Так как мы используем $1 в замене, которая является захваченной группой, мы сохраняем только второй токен. Поэтому единственный способ для END выжить - это попасть в группу захвата, будучи первым после START.

Например, для текста END START 123 END abc END. Регулярное выражение найдет следующие совпадения и сохранит, пропустит или удалит их соответственно:

  • END - Удалено
  • (START 123 END) - Захвачено
  • a - Пропустить
  • b - Пропустить
  • c - Пропустить
  • END - Удалено

Рабочий пример: http://ideone.com/suVYh

Ответ 2

Это пример учебника нерегулярного языка (START и END являются эквивалентом открывающих и закрывающих круглых скобок). Это означает, что вы не можете сопоставить этот язык с простым регулярным выражением. Вы можете сделать это с определенной глубиной со сложным регулярным выражением, но не произвольной глубиной.

Вам нужно написать парсер языка.

Связанное чтение:

http://www.amazon.com/Introduction-Automata-Theory-Languages-Comput/dp/0321462254/ref=sr_1_1?ie=UTF8& QID = 1291768284 & ср = 8-1

Ответ 3

Невозможно написать регулярное выражение для всего возможного синтаксиса. Для вашего случая вам может понадобиться контекстный свободный синтаксический анализатор, такой как восходящий или потоковый. См.: http://en.wikipedia.org/wiki/Formal_grammar