Не понимаю, я в условие написал {1,} это значит, если повторяется больше одного раза, то это всё удалить, но почему не во всех случаях удаляет?
echo preg_replace('#([\w]+)\s\1{1,}#', '$1', 'hello my my my my my world');
/hello world world - работает
//hello world world world - не работает
//hello world world world world - не работает
//hello hello world - работает
//hello hello hello hello world - плохо работает
//hello my my world - работает
//hello my my my world - плохо работает
//hello my my my my my world - hello my my my my my world
#(\w+)(\s+\1)+#
(\w+) - 1-ая группа захвата, можно сказать что слово, хотя тут можно поспорить;
(\s+\1)+ - 2-ая повторяющаяся группа захвата, от которой вы хотите избавиться и состоит она из 1-го или более пробельных символов и слова из первой группы захвата, так как между словами пробелы все-таки должны быть!
Пример https://regex101.com/r/q1OhHr/1
P.S. Можно еще и флаг i добавить, чтобы регистронезависимая проверка была и флаг u для Юникода.
Слово \w+ и любое число таких же слов с пробельным префиксом \s+\1 меняем на само слово $1. Тесты для самопроверки:
$tests = [
'hello world world' => 'hello world',
'hello world world world' => 'hello world',
'hello world world world world' => 'hello world',
'hello hello world' => 'hello world',
'hello hello hello hello world' => 'hello world',
'hello my my world' => 'hello my world',
'hello my my my world' => 'hello my world',
'hello my my my my my world - hello my my my my my world' => 'hello my world - hello my world',
];
foreach ($tests as $in => $expected) {
$actual = preg_replace('/(\w+)(\s+\1)+/isu', '$1', $in);
assert($expected === $actual, "\n--- {$expected}\n+++ {$actual}\n");
}
Если код не вывалил описание ошибок в ассёртах, то всё ОК!
Сборка персонального компьютера от Artline: умный выбор для современных пользователей