2015-06-11 5 views
2

Я пытаюсь построить шаблон для многострочнога строки, которая должна начинаться с <?php или whitespace + <?php и НЕ конца с ?> или ?> + whitespace.Regex для многострочнога строки с PHP preg_match

Моя попытка /^\s?<\?php.*[^>]\s?$/s, но это не сработало. Также попробовал негативный взгляд - бесполезно.

Любая идея? Спасибо заранее.

+0

Если вы просто 'trim()' вначале, это становится намного проще и может быть выполнено с помощью простых вызовов 'str_pos' – adeneo

+0

Невозможно в моем случае. Здесь я просто подготавливаю шаблоны, чтобы передать их другому сценарию. – autarq

ответ

2

Вы можете использовать

(?s)^\s*<\?php(?!.*\?>\s*$).*+$ 

См demo

Regex объяснение:

  • (?s) - Включить SingleLine режим для всего шаблона для ., чтобы соответствовать новой строки
  • ^ - начало строки
  • \s* - Дополнительный пробел, 0 или более повторения
  • <\?php - Буквальный <?php
  • (?!.*\?>\s*$) - Прогностические проверки, если строка не заканчивается ?>whitespace
  • .*+$ - спичек без возвратов любого символов до конца строки.

possessive quantifier (как в .*+) позволяет потреблять символы один раз, в 1 ход, и никогда не возвращаться в поисках возможных перестановок.

Потенциальные кванторы - это способ предотвратить движение двигателя regex от при попытках всех перестановок. Это в первую очередь полезно для производительности .

И мы не будем использовать явно выраженные глаголы SKIP-FAIL.

+1

Хорошее ясное и хорошее объяснение, * люблю его *! :) – Rizier123

+1

Я думаю, что OP хочет ** НЕ заканчивать '?>' Или '?> Whitespace *' ** – anubhava

+0

Да, это работает, хотя я не поклонник двойного негативного взгляда. Однако, честно говоря, я не ответил на ваш ответ другим. – anubhava

2

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

'/^\s*<\?php(?:.(?!\?>\s*$))*$/s' 

RegEx Demo

  • ^\s*<\?php Удачные факультативные пробельные и буквального <?php в начале строки.
  • (?:.(?!\?>\s*$))* будет соответствовать любым 0 или более символам, которые не заканчиваются ?>whitespace*, используя отрицательный результат.

Update: Для повышения эффективности этого PCRE регулярное выражение будет работать быстрее, чем предыдущая:

'/^\s*<\?php(?>.*\?>\s*$(*SKIP)(*F)|.*+$)/s' 

RegEx Demo 2

  • (*FAIL) ведет себя как неисправного отрицательного утверждения и является синоним для (?!)
  • (*SKIP) определяет точку, за которой движок регулярных выражений не допускаются, чтобы вернуться назад, когда подшаблон терпит неудачу позже
  • (*SKIP)(*FAIL) вместе обеспечивает хорошую альтернативу ограничения, что вы не можете иметь переменную длину в назад 'выше регулярном выражении.
Смежные вопросы