2013-05-21 5 views
2

У меня есть регулярное выражение (?<={% start %}).*?(?={% end %}), которое соответствует всем между двумя пользовательскими тегами.Как совместить несколько (N) пробелов в регулярных выражениях регулярных выражений?

Проблема состоит в том, что, если есть пробелы внутри тегов (например, «{%       старт%}») и добавить \s+? состояние, регулярное выражение не удается. Следующий код не работает: (?<={%\s+?start\s+?%}).*?(?={%\s+?end\s+?%}) и я получаю сообщение об ошибке в PHP:

preg_match_all(): Compilation failed: lookbehind assertion is not fixed length at offset 25 

же регулярное выражение работает, если удалить опережения /: ({%\s+?(start|end)\s+%}) назад '.

Просьба сообщить.

+0

Есть ли у вас какой-то образец текста? –

+1

В зависимости от языка, lookbehind не может быть переменной длины. – Toto

+1

Вот пример текста: http://pastebin.com/AUX1hd2T Я также обновил свой вопрос с сообщением об ошибке. Я использую PHP. – MarkL

ответ

3

Описание

Попробуйте permlink

[{]%\s*?\b([^}]*start[^}]*)\b\s*?%[}]\s*?\b(.*?)\b\s*?[{]%\s*\b([^}]*end[^}]*)\b\s*%[}] 

Это будет соответствовать всему тексту внутри вашей {% и %} скобки, и будет автоматически обрезать текст, прежде чем положить значение в свои группы.

Группа 0 получает всю строку соответствия

  1. получает текст Открывающий тег
  2. Получает внутренний текст
  3. получает текст конечный тег

enter image description here

Отказ

Это, вероятно, будет иметь некоторые случаи ребер, когда регулярное выражение будет терпеть неудачу, если у вас есть сложные данные, вложенные в sub, если так, то использование regex, вероятно, не будет лучшим инструментом для этой задачи.

Резюме

[{]%\s*?\b([^}]*start[^}]*)\b\s*?%[}]\s*?\b(.*?)\b\s*?[{]%\s*\b([^}]*end[^}]*)\b\s*%[}] 
Char class [{] matches one of the following chars: { 
% Literal `%` 
\s 0 to infinite times [lazy] Whitespace [\t \r\n\f] 
\b Word boundary: match in between (^\w|\w$|\W\w|\w\W) 
1st Capturing group ([^}]*start[^}]*) 
Negated char class [^}] infinite to 0 times matches any char except: } 
start Literal `start` 
Negated char class [^}] infinite to 0 times matches any char except: } 
\b Word boundary: match in between (^\w|\w$|\W\w|\w\W) 
\s 0 to infinite times [lazy] Whitespace [\t \r\n\f] 
% Literal `%` 
Char class [}] matches one of the following chars: } 
\s 0 to infinite times [lazy] Whitespace [\t \r\n\f] 
\b Word boundary: match in between (^\w|\w$|\W\w|\w\W) 
2nd Capturing group (.*?) 
. 0 to infinite times [lazy] Any character (except newline) 
\b Word boundary: match in between (^\w|\w$|\W\w|\w\W) 
\s 0 to infinite times [lazy] Whitespace [\t \r\n\f] 
Char class [{] matches one of the following chars: { 
% Literal `%` 
\s infinite to 0 times Whitespace [\t \r\n\f] 
\b Word boundary: match in between (^\w|\w$|\W\w|\w\W) 
3rd Capturing group ([^}]*end[^}]*) 
Negated char class [^}] infinite to 0 times matches any char except: } 
end Literal `end` 
Negated char class [^}] infinite to 0 times matches any char except: } 
\b Word boundary: match in between (^\w|\w$|\W\w|\w\W) 
\s infinite to 0 times Whitespace [\t \r\n\f] 
% Literal `%` 
Char class [}] matches one of the following chars: } 

PHP пример

с образцом текста {% start %} this is a sample text 1 {% end %}{% start %} this is a sample text 2 {% end %}

<?php 
$sourcestring="your source string"; 
preg_match_all('/[{]%\s*?\b([^}]*start[^}]*)\b\s*?%[}]\s*?\b(.*?)\b\s*?[{]%\s*\b([^}]*end[^}]*)\b\s*%[}]/i',$sourcestring,$matches); 
echo "<pre>".print_r($matches,true); 
?> 

$matches Array: 
(
    [0] => Array 
     (
      [0] => {% start %} this is a sample text 1 {% end %} 
      [1] => {% start %} this is a sample text 2 {% end %} 
     ) 

    [1] => Array 
     (
      [0] => start 
      [1] => start 
     ) 

    [2] => Array 
     (
      [0] => this is a sample text 1 
      [1] => this is a sample text 2 
     ) 

    [3] => Array 
     (
      [0] => end 
      [1] => end 
     ) 

) 
+0

Спасибо, но мне нужно регулярное выражение для соответствия текста между тегами, а не внутри. – MarkL

+0

Отредактированный ответ satisify –

+0

Спасибо, но PHP, похоже, не принимает его. Вы можете протестировать его здесь: http://www.pagecolumn.com/tool/pregtest.htm (используйте PCRE и PREG_MATCH_ALL). – MarkL