Я пытаюсь создать регулярное выражение, которое соответствует пяти последним "словам" ввода, где "слово" определяется как все, что соответствует [^ ]+
или [^ ]*<[^>]*>[^ ]*
(так что все, разделенные пробелами, но считая пробелы между <
и >
как буквы)
Я попробовал это:
/([^ ]+(?:(?<!<[^>]+) +(?![^<]*>)(?:.*?)){0,4})$/
но это дает мне ошибку, что lookbehind должна быть фиксированной длины.
Скажем, у меня есть следующая строка:
'It\ just that he <span class="verb">appear</span>ed rather late.'
он должен соответствовать
'that he <span class="verb">appear</span>ed rather late.'
Я думаю, что ваше решение уже было довольно близко. См. Следующий:
$str = 'It\ just that he <span class="verb">appear</span>ed rather late.';
$reg = '/(([^ ]*<[^>]*>[^ ]*)+|[^ ]+)/'; // let me know if you need explanation
if (preg_match_all($reg, $str, $m)) { // "_all" to match more than one
$m = array_slice($m[0], -5, 5, true); // last 5 words
//$m = implode(' ', $m); // uncomment this if you want a string instead of array
print_r($m);
}
Возвращает:
Array
(
[2] => that
[3] => he
[4] => <span class="verb">appear</span>ed
[5] => rather
[6] => late.
)
<em><span class="verb">appear</span>ed</em>
), но, к счастью, это не так для меня.
Простой способ:
preg_match('~^(?:\s*[^>\s]*(?:>[^<]*<[^>\s]*)*){0,5}~', strrev(rtrim($str)), $m);
$result = strrev($m[0]);
span class="verb">appeared rather late.
while (preg_match('/<[^> ]* /',$input)) $input = preg_replace('/(<[^> ]*) /','$1'."\0",$input);
preg_match('/(?:(?:[^ ]+) ){0,4}[^ ]*$/',$input,$match);
$input = str_replace("\0"," ");
$match[0] = str_replace("\0"," ");
но это кажется довольно грубым и может привести к поломке, если используемый символ (\ 0 здесь) уже появляется на входе