Удалить последние два слова из строки

Я совершенно новичок в preg_replace, но приведенный ниже код удаляет последнее слово из моей строки:

preg_replace('/\W\w+\s*(\W*)$/', '$1', $var);

Я пытаюсь изменить его, чтобы удалить последние два слова.

Единственное, что я мог придумать, это заменить $1 на $2, но это, похоже, вообще не имеет никакого эффекта и, вероятно, было просто глупо :/

Рассматриваемая строка выглядит примерно так:

Lorem ipsum dolor sit amet. Source: LOREM

Я хочу удалить Source: LOREM


person r0skar    schedule 10.05.2012    source источник
comment
Как вы определяете слово? а какие символы могут разделять слова?   -  person Yet Another Geek    schedule 11.05.2012
comment
$1 относится не к количеству, а к порядку. Это ваша первая совпавшая последовательность.   -  person Sampson    schedule 11.05.2012
comment
@YetAnotherGeek Смотрите мой обновленный вопрос   -  person r0skar    schedule 11.05.2012
comment
Каков будет ожидаемый результат для этой строки: Нравится ли мне сыр? Нет.   -  person Jeff Lambert    schedule 11.05.2012
comment
Или вы можете просто дважды запустить подпрограмму, которая удаляет последнее слово.   -  person andrewsi    schedule 11.05.2012


Ответы (3)


Простое регулярное выражение может соответствовать пробелу, за которым следует любое количество букв (или двоеточие), за которым следует пробел, за которым следует любое количество букв в конце строки:

$str = "Lorem ipsum dolor sit amet. Source: LOREM";
$str = preg_replace( "/\s[a-z:]+\s[a-z]+$/i", "", $str );

// Lorem ipsum dolor sit amet.
echo $str;

Выражение разбито следующим образом:

\s       // Single space
[a-z:]+  // Any letter, a to z, or a colon, 1 or more times
\s       // Single space
[a-z]+   // Any letter, a to z, 1 or more times
$        // End of string

Демонстрация: http://codepad.org/G22LnDDY

Еще один метод — использовать explode для создания массива слов и удаления последних двух.

$str = "Lorem ipsum dolor sit amet. Source: LOREM";
$words = explode( " ", $str );
array_splice( $words, -2 );

// Lorem ipsum dolor sit amet.
echo implode( " ", $words );

Демонстрация: http://codepad.org/6XwqvwuP

person Sampson    schedule 10.05.2012
comment
Спасибо за все ответы, но ни один из них не работает (Source: Lorem не удален). Это странно, так как этот код для удаления только 1 слова работает нормально. Вероятно, это проблема, связанная с моим кодом. Я буду продолжать пробовать это, и если я не исправлю это, я обновлю свой вопрос фрагментом кода. Я надеюсь, что все в порядке, если я не приму какой-либо ответ на данный момент. - person r0skar; 11.05.2012
comment
@Andrej Оба вышеуказанных метода работают. Проверьте свой код еще раз. Я предоставил ссылки на две функциональные демонстрации, с которыми вы можете поиграть. - person Sampson; 11.05.2012
comment
Большое спасибо за ваши усилия, Джонатан. Codepad.org выглядит как отличный способ протестировать весь мой фрагмент кода! Я уверен, что рано или поздно у меня все получится! p.s. может ли проблема заключаться в том, что у меня есть несколько строк, и я использую выражение для каждого цикла? - person r0skar; 11.05.2012
comment
@Andrej Дайте мне ссылку на кодовую панель для вашей настройки, и я дам вам знать. - person Sampson; 11.05.2012
comment
Я разместил его на сайте codepad.org/9ShnX8xP . Однако весь код там не работает, так как отсутствует файл (simplehtmldomparser). Если вам нужно, чтобы я включил и это, просто дайте мне знать! И еще раз спасибо, что нашли время, чтобы посмотреть на него! - person r0skar; 11.05.2012
comment
@Andrej Что выводит строка echo implode( " ", $words );? - person Sampson; 11.05.2012
comment
Можете ли вы сделать var_dump( $descr->plaintext ); и поделиться результатом? - person Sampson; 11.05.2012
comment
Я, наверное, сейчас очень глуп, но в примере, который вы сделали, я все еще вижу Source: CBS в поле «Вывод»? - person r0skar; 11.05.2012
comment
Я думаю, вы ищете не в том месте: i.imgur.com/hsbBu.png Теперь, как на выходе нет нескольких новых строк, как на входе. - person Sampson; 11.05.2012
comment
О, я понял! Итак, я бы взял этот вывод сейчас и использовал его для одного из различных методов, которые были опубликованы здесь? Попытка -› РАБОТАЕТ! :) Большое спасибо за ваши усилия! Я бы дважды проголосовал за ваш ответ, если бы мог! - person r0skar; 11.05.2012

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

$words = explode(' ', 'Lorem ipsum dolor sit amet. Source: LOREM');
if (count($words) >= 2) {
    array_pop($words);
    array_pop($words);
}
$words = implode(' ', $words);

Or:

$words = explode(' ', 'Lorem ipsum dolor sit amet. Source: LOREM');
if (count($words) >= 2) {
    $words = array_slice($words, 0, count($words) - 2);
}
$words = implode(' ', $words);
person Michael Robinson    schedule 10.05.2012
comment
Спасибо за все ответы, но ни один из них не работает (Source: Lorem не удален). Это странно, так как этот код для удаления только 1 слова работает нормально. Вероятно, это проблема, связанная с моим кодом. Я буду продолжать пробовать это, и если я не исправлю это, я обновлю свой вопрос фрагментом кода. Я надеюсь, что все в порядке, если я не приму какой-либо ответ на данный момент. - person r0skar; 11.05.2012

$1 на самом деле является сгруппированным захватом для замены, поэтому думайте об этом как о $n, $n+1. У вас есть только 1 группа в вашем регулярном выражении паренс (). Так что вам понадобится второй набор. Если вам на самом деле не нужно что-то менять, вы можете использовать более целенаправленный подход.

.*(?=\s\D+\s)

Должен сделать вас намного ближе. Кроме того, меня спасает жизнь (хорошо, экономит время) http://regexpal.com/. код RegEx без него.

person Mike Petty    schedule 10.05.2012