Ответ 1
Попробуйте это регулярное выражение:
\b(\w+)\s+\1\b
Здесь \b
- граница слова, а \1
ссылается на захваченное совпадение первой группы.
Я новичок в регулярном выражении, и я не могу понять, как написать одно регулярное выражение, которое "соответствовало бы" любым повторяющимся последовательным словам, таким как:
Париж в весенний период.
Не то, чтобы это было связано.
Почему Вы смеетесь? Я мои мои регулярные выражения, ЧТО плохо?
Есть ли одно регулярное выражение, которое будет соответствовать всем выделенным жирным строкам?
Попробуйте это регулярное выражение:
\b(\w+)\s+\1\b
Здесь \b
- граница слова, а \1
ссылается на захваченное совпадение первой группы.
Я считаю, что это регулярное выражение обрабатывает больше ситуаций:
/(\b\S+\b)\s+\b\1\b/
Хороший выбор тестовых строк можно найти здесь: http://callumacrae.github.com/regex-tuesday/challenge1.html
Широко используемая библиотека PCRE может обрабатывать такие ситуации (однако вы не достигнете с совместимыми с POSIX системами регулярных выражений):
(\b\w+\b)\W+\1
Попробуйте сделать это ниже RE
() * Повторение снова
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();
}
Нет. Это нерегулярная грамматика. Могут существовать регулярные выражения, зависящие от языка и языка, которые вы можете использовать, но нет универсального регулярного выражения, которое может это сделать.
Вот один из них, который несколько раз ловит несколько слов:
(\b\w+\b)(\s+\1)+
Пример в Javascript: Хорошие части могут быть адаптированы для этого:
var doubled_words = /([A-Za-z\u00C0-\u1FFF\u2800-\uFFFD]+)\s+\1(?:\s|$)/gi;
\ b использует \w для границ слова, где \w эквивалентно [0-9A-Z_a-z]. Если вы не возражаете против этого ограничения, принятый ответ в порядке.
Это регулярное выражение, которое я использую для удаления повторяющихся фраз в моем боксе с подстановкой:
(\S+\s*)\1{2,}
(\S+\s*)
ищет любую строку символов, которая не является пробелом, а затем пробегает.
\1{2,}
затем ищет более двух экземпляров этой фразы в строке для соответствия. Если есть три фразы, которые идентичны, они совпадают.
Это выражение (вдохновленное Майком, выше), похоже, улавливает все дубликаты, тройки и т.д., В том числе те, которые находятся в конце строки, что у большинства других нет:
/(^|\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
Поскольку некоторые разработчики приходят на эту страницу в поисках решения, которое не только устраняет повторяющиеся последовательные не-пробельные подстроки, но и три раза и дальше, я покажу адаптированный шаблон.
Шаблон: /(\b\S+)(?:\S+\1\b)+/
(образец шаблона)
Заменить: $1
(заменяет совпадение полной строки с группой захвата # 1)
Этот шаблон с жадностью соответствует "целой" подстроке без пробелов, затем требуется одна или несколько копий согласованной подстроки, которые могут быть разделены одним или несколькими символами пробела (пробел, табуляция, новая строка и т.д.).
В частности:
\b
(границы слова) жизненно важны, чтобы гарантировать, что частичные слова не совпадают.+
(один или несколько квантификаторов) в группе, не участвующей в захвате, более подходит, чем *
потому что *
будет "беспокоить" механизм регулярных выражений для захвата и замены однотонных вхождений - это расточительный дизайн шаблонов.* обратите внимание, что если вы имеете дело с предложениями или вводными строками с пунктуацией, то шаблон необходимо будет уточнить.
([a-zA-Z]+)\s+\1
Следующее будет работать для алфавитных строк Здесь \1 будет зафиксировано первое совпадение. Просто добавьте действующее регулярное выражение внутри []
Используйте это, если вы хотите проверять регистр без повторения слов.
(?i)\\b(\\w+)\\s+\\1\\b
Попробуйте это регулярное выражение, которое может поймать 2 или более дублирующих слова и оставить только одно слово. И повторяющиеся слова не обязательно должны быть последовательными.
/\b(\w+)\b(?=.*?\b\1\b)/ig
Здесь \b
используется для Word Boundary,? ?=
Используется для позитивного просмотра, а \1
используется для обратной привязки.
Выражение ниже должно работать правильно, чтобы найти любое количество последовательных слов. Соответствие может быть без учета регистра.
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 заменяет все последовательные совпадающие слова на первый экземпляр слова.
Я ищу синтаксис для удаления дублированного слова. Я нашел это выражение, которое работает
/(\b\w+\b)(?=.*\b\1\b)/
Однако он удаляет первое повторное слово, которое находит, и мне нужно, чтобы оно было вторым; это возможно? Другой вопрос: есть ли выражение для удаления последнего слова в предложении? Заранее спасибо!