Страницы

Поиск по вопросам

среда, 4 марта 2020 г.

Удаление двойных и более слов

#php #регулярные_выражения


Не понимаю, я в условие написал {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

    


Ответы

Ответ 1



#(\w+)(\s+\1)+# (\w+) - 1-ая группа захвата, можно сказать что слово, хотя тут можно поспорить; (\s+\1)+ - 2-ая повторяющаяся группа захвата, от которой вы хотите избавиться и состоит она из 1-го или более пробельных символов и слова из первой группы захвата, так как между словами пробелы все-таки должны быть! Пример https://regex101.com/r/q1OhHr/1 P.S. Можно еще и флаг i добавить, чтобы регистронезависимая проверка была и флаг u для Юникода.

Ответ 2



Слово \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"); } Если код не вывалил описание ошибок в ассёртах, то всё ОК!

Комментариев нет:

Отправить комментарий