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

Я новичок в регулярном выражении, и я не могу понять, как написать одно регулярное выражение, которое "соответствовало бы" любым повторяющимся последовательным словам, таким как:

Париж в весенний период.

Не то, чтобы это было связано.

Почему Вы смеетесь? Я мои мои регулярные выражения, ЧТО плохо?

Есть ли одно регулярное выражение, которое будет соответствовать всем выделенным жирным строкам?

Ответ 1

Попробуйте это регулярное выражение:

\b(\w+)\s+\1\b

Здесь \b - граница слова, а \1 ссылается на захваченное совпадение первой группы.

Ответ 2

Я считаю, что это регулярное выражение обрабатывает больше ситуаций:

/(\b\S+\b)\s+\b\1\b/

Хороший выбор тестовых строк можно найти здесь: http://callumacrae.github.com/regex-tuesday/challenge1.html

Ответ 3

Широко используемая библиотека PCRE может обрабатывать такие ситуации (однако вы не достигнете с совместимыми с POSIX системами регулярных выражений):

(\b\w+\b)\W+\1

Ответ 4

Попробуйте сделать это ниже RE

  • \b начало границы слова word
  • \W + любой символ слова
  • \1 уже сопоставленное слово
  • \b конец слова
  • () * Повторение снова

    public static void main(String[] args) {
    
        String regex = "\\b(\\w+)(\\b\\W+\\b\\1\\b)*";//  "/* Write a RegEx matching repeated words here. */";
        Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE/* Insert the correct Pattern flag here.*/);
    
        Scanner in = new Scanner(System.in);
    
        int numSentences = Integer.parseInt(in.nextLine());
    
        while (numSentences-- > 0) {
            String input = in.nextLine();
    
            Matcher m = p.matcher(input);
    
            // Check for subsequences of input that match the compiled pattern
            while (m.find()) {
                input = input.replaceAll(m.group(0),m.group(1));
            }
    
            // Prints the modified sentence.
            System.out.println(input);
        }
    
        in.close();
    }
    

Ответ 5

Нет. Это нерегулярная грамматика. Могут существовать регулярные выражения, зависящие от языка и языка, которые вы можете использовать, но нет универсального регулярного выражения, которое может это сделать.

Ответ 6

Вот один из них, который несколько раз ловит несколько слов:

(\b\w+\b)(\s+\1)+

Ответ 7

Пример в Javascript: Хорошие части могут быть адаптированы для этого:

var doubled_words = /([A-Za-z\u00C0-\u1FFF\u2800-\uFFFD]+)\s+\1(?:\s|$)/gi;

\ b использует \w для границ слова, где \w эквивалентно [0-9A-Z_a-z]. Если вы не возражаете против этого ограничения, принятый ответ в порядке.

Ответ 8

Это регулярное выражение, которое я использую для удаления повторяющихся фраз в моем боксе с подстановкой:

(\S+\s*)\1{2,}

(\S+\s*) ищет любую строку символов, которая не является пробелом, а затем пробегает.

\1{2,} затем ищет более двух экземпляров этой фразы в строке для соответствия. Если есть три фразы, которые идентичны, они совпадают.

Ответ 9

Это выражение (вдохновленное Майком, выше), похоже, улавливает все дубликаты, тройки и т.д., В том числе те, которые находятся в конце строки, что у большинства других нет:

/(^|\s+)(\S+)(($|\s+)\2)+/g, "$1$2")

Я знаю, что вопрос задан только для дубликатов, но в трех экземплярах есть всего два дубликата рядом друг с другом :)

Во-первых, я положил (^|\s+) чтобы убедиться, что он начинается с полного слова, иначе "детский стейк" перейдет к "child'steak" (совпадение "s"). Затем он соответствует всем полным словам ((\b\s+\b)), за которым следует конец строки ($) или количество пробелов (\s+), причем все повторяется несколько раз.

Я пробовал это так и работал хорошо:

var s = "here here here     here is ahi-ahi ahi-ahi ahi-ahi joe joe joe joe joe the result result     result";
print( s.replace( /(\b\S+\b)(($|\s+)\1)+/g, "$1"))         
--> here is ahi-ahi joe the result

Ответ 10

Поскольку некоторые разработчики приходят на эту страницу в поисках решения, которое не только устраняет повторяющиеся последовательные не-пробельные подстроки, но и три раза и дальше, я покажу адаптированный шаблон.

Шаблон: /(\b\S+)(?:\S+\1\b)+/ (образец шаблона)
Заменить: $1 (заменяет совпадение полной строки с группой захвата # 1)

Этот шаблон с жадностью соответствует "целой" подстроке без пробелов, затем требуется одна или несколько копий согласованной подстроки, которые могут быть разделены одним или несколькими символами пробела (пробел, табуляция, новая строка и т.д.).

В частности:

  • Символы \b (границы слова) жизненно важны, чтобы гарантировать, что частичные слова не совпадают.
  • Вторая скобка - это не захватывающая группа, потому что эту подстроку переменной ширины не нужно захватывать - только совпадающую/абсорбированную.
  • + (один или несколько квантификаторов) в группе, не участвующей в захвате, более подходит, чем * потому что * будет "беспокоить" механизм регулярных выражений для захвата и замены однотонных вхождений - это расточительный дизайн шаблонов.

* обратите внимание, что если вы имеете дело с предложениями или вводными строками с пунктуацией, то шаблон необходимо будет уточнить.

Ответ 11

([a-zA-Z]+)\s+\1

Следующее будет работать для алфавитных строк Здесь \1 будет зафиксировано первое совпадение. Просто добавьте действующее регулярное выражение внутри []

Ответ 12

Используйте это, если вы хотите проверять регистр без повторения слов.

(?i)\\b(\\w+)\\s+\\1\\b

Ответ 13

Regex to Strip 2+ повторяющиеся слова (последовательные/непоследовательные слова)

Попробуйте это регулярное выражение, которое может поймать 2 или более дублирующих слова и оставить только одно слово. И повторяющиеся слова не обязательно должны быть последовательными.

/\b(\w+)\b(?=.*?\b\1\b)/ig

Здесь \b используется для Word Boundary,? ?= Используется для позитивного просмотра, а \1 используется для обратной привязки.

Пример источника

Ответ 14

Выражение ниже должно работать правильно, чтобы найти любое количество последовательных слов. Соответствие может быть без учета регистра.

String regex = "\\b(\\w+)(\\s+\\1\\b)*";
Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);

Matcher m = p.matcher(input);

// Check for subsequences of input that match the compiled pattern
while (m.find()) {
     input = input.replaceAll(m.group(0), m.group(1));
}

Пример ввода: до свидания до свидания GooDbYe

Пример вывода: до свидания

Объяснение:

Выражение регулярного выражения:

\b: начало границы слова

\w+: любое количество символов слова

(\ s+\1\b) *: любое количество пробелов, за которыми следует слово, совпадающее с предыдущим словом и заканчивающее границу слова. Вся вещь, завернутая в *, помогает найти более одного повторения.

Группировка:

m.group(0): должен содержать соответствующую группу в указанном выше случае. До свидания, до свидания GooDbYe

m.group(1): должен содержать первое слово сопоставленного шаблона в вышеприведенном случае. До свидания

Метод Replace заменяет все последовательные совпадающие слова на первый экземпляр слова.

Ответ 15

Я ищу синтаксис для удаления дублированного слова. Я нашел это выражение, которое работает
/(\b\w+\b)(?=.*\b\1\b)/

Однако он удаляет первое повторное слово, которое находит, и мне нужно, чтобы оно было вторым; это возможно? Другой вопрос: есть ли выражение для удаления последнего слова в предложении? Заранее спасибо!