Соответствует ограниченному количеству пробелов, игнорируя те, которые являются частью тега

1

Я пытаюсь создать регулярное выражение, которое соответствует пяти последним "словам" ввода, где "слово" определяется как все, что соответствует [^ ]+ или [^ ]*<[^>]*>[^ ]* (так что все, разделенные пробелами, но считая пробелы между < и > как буквы)

Я попробовал это:

/([^ ]+(?:(?<!<[^>]+) +(?![^<]*>)(?:.*?)){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.'
  • 0
    Пожалуйста, добавьте одну или несколько примеров строк и ожидаемый результат.
  • 0
    Один из способов был бы в 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 здесь) уже появляется на входе
Показать ещё 3 комментария
Теги:
pcre

2 ответа

1

Я думаю, что ваше решение уже было довольно близко. См. Следующий:

$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.
)
  • 0
    Приятно. Работает для моего конкретного случая. Вероятно, не будет работать, если бы были вложенные теги (скажем, если было что-то вроде <em><span class="verb">appear</span>ed</em> ), но, к счастью, это не так для меня.
  • 0
    Правильно. На самом деле может быть больше вопросов. Помните: stackoverflow.com/questions/1732348/…
0

Простой способ:

preg_match('~^(?:\s*[^>\s]*(?:>[^<]*<[^>\s]*)*){0,5}~', strrev(rtrim($str)), $m);
$result = strrev($m[0]);
  • 0
    это возвращает span class="verb">appeared rather late.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню