Регулярное выражение для повторяющихся последовательностей символов

Я хочу использовать регулярное выражение для удаления повторяющихся последовательностей символов (слов) из строки. Мой вопрос похож на вопрос под названием регулярное выражение для повторяющихся слов, но у меня есть некоторые дополнительные требования.

  1. Мне нужно включить дополнительные символы. Принятый ответ на связанный вопрос определяет только слова, состоящие из буквенно-цифровых символов, но мне нужно включить в определение слова символы, такие как «@».

  2. Мне нужно сопоставить несколько повторений шаблона. Если слово повторяется три раза, принятый ответ на связанный вопрос удаляет только один из дубликатов, но мне нужно удалить их оба.

Вот пример строки, которую я использую для тестирования:

hello me now @@@ @@@ @@@ then method me @@@

Мой желаемый результат:

hello me now @@@ then method me @@@

Вы можете сопоставить (?<!\S)(\S+)(?:\s+\1)+ и заменить группой 1 $1 См. regex101.com/r/tlsMRh/1

The fourth bird 05.09.2024 15:42
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ключами к решению этой проблемы являются:

  1. Используйте просмотр назад.
  2. Ищите пробелы (\s) и непробелы (\S).

Вот регулярное выражение, которое вам нужно: /(?<=(\S+)\s+)\1\s+/g

Вот демонстрация того, как это работает.

Вот скриншот демонстрации.


Теперь я объясню процесс создания этого регулярного выражения. Для начала сформулируем цель. Цель состоит в том, чтобы сопоставить любое слово, которое совпадает с предыдущим словом, чтобы мы могли его удалить, то есть ничем заменить. Итак, давайте пройдемся по процессу:

  1. Первый шаг — сопоставить каждое слово в вашей строке. Обычно вы используете \w+, но он соответствует только буквенно-цифровым символам. Вместо этого используйте \S+, который соответствует всем символам, которые не считаются пробелами. Обратите внимание, что оно соответствует «@@@» так же, как и обычным словам.

  1. Второй шаг — сопоставить слово только в том случае, если ему предшествует другое слово. Для этого мы используем выражение просмотра назад (?<= ... ), ищем слово \S+, за которым следует пробел \s+. На скриншоте видно, что самое первое слово в строке больше не соответствует. Идеальный.

  1. Третий шаг — сопоставить слово, только если оно совпадает со словом, предшествующим ему. Для этого нам нужно захватить предыдущее слово (поместив скобки вокруг \S+ внутри выражения просмотра назад), а затем обратиться к этой захваченной группе в нашем совпадении (заменив исходное \S+ на \1).

  1. Обратите внимание на скриншот выше, что после удаления спичек (замены их ничем) у нас все еще остаются лишние пробелы. Мы можем избежать этого, включив любые пробелы после слова в исходное выражение соответствия, поэтому мы просто добавляем \s+ в конец. Это подводит нас к окончательному результату, который я проиллюстрировал в начале этого ответа.

/(?<=(\S+)\s+)\1\s+/g

Другие вопросы по теме

Похожие вопросы

Регулярное выражение ReactJS не работает с разделенной строкой
PowerShell Regex: удаление определенных частей строки на основе шаблонов
Удаление всех слов, кроме первой буквы, с помощью регулярного выражения в LibreOffice Writer
Почему некоторые функции регулярных выражений возвращают объект соответствия, а некоторые нет?
Регулярное выражение для проверки того, содержит ли ввод две заданные строки, а часть между ними не содержит ни одного элемента из набора указанных строк
Regex: сопоставить кратчайший шаблон между двумя возможными разделителями
Использованиеdependent_wider_regex для создания новой строки для каждого совпадения в R
Добавить новые строки перед выбранными символами дефиса
Написание Regex для обработки дополнительных символов с плавающей запятой в начале строки?
Как извлечь из строки только уникальные значения, используя регулярное выражение в Python?