如何在正则表达式中去除重复项

5
假设我有一个字符串 "cats cats cats and dogs dogs dogs.",我需要使用什么正则表达式才能将该字符串替换为 "cats and dogs.",即删除重复项。但是,该表达式必须仅删除相邻的重复项。例如:
"cats cats cats and dogs dogs dogs and cats cats and dogs dogs"
将返回:
"cats and dogs and cats and dogs"

请查看https://dev59.com/aEjSa4cB1Zd3GeqPDTWp,它可能会对你的问题有所帮助。 - Jason Evans
4个回答

9
resultString = Regex.Replace(subjectString, @"\b(\w+)(?:\s+\1\b)+", "$1");

将在一次调用中完成所有替换。

说明:

\b                 # assert that we are at a word boundary
                   # (we only want to match whole words)
(\w+)              # match one word, capture into backreference #1
(?:                # start of non-capturing, repeating group
   \s+             # match at least one space
   \1              # match the same word as previously captured
   \b              # as long as we match it completely
)+                 # do this at least once

Tim,你是一个正则表达式大师。尊敬! :) - Koen
+1,因为这个表达式可行,而且还有解释。 - Alberto De Caro

2

(\w+)\s+\1替换为$1

在循环中执行此操作,直到不再找到匹配项。仅设置global标志是不够的,因为它不会替换cats cats cats中的第三个cats

在正则表达式中\1指的是第一个捕获组的内容。

尝试:

str = "cats cats cats and dogs dogs dogs and cats cats and dogs dogs";
str = Regex.Replace(str, @"(\b\w+\b)\s+(\1(\s+|$))+", "$1 ");
Console.WriteLine(str);

我正在使用这段代码:replacer = Regex.Replace(replacer, @"([\n]+)[\s+]?\1", string.Empty); 但它似乎不起作用。然而在 rubular 上是可以工作的 http://www.rubular.com/r/Ey6wrLYXNw - Immanu'el Smith
@Emmanuel 请尝试使用 str = Regex.Replace(str, @"(\w+)\s+\1", "$1"); - Amarghosh

1
毫无疑问,可能存在更小的正则表达式,但这个似乎能够解决问题:
string somestring = "cats cats cats and dogs dogs dogs and cats cats and dogs dogs";
Regex regex = new Regex(@"(\w+)\s(?:\1\s)*(?:\1(\s|$))");
string result = regex.Replace(somestring, "$1$2");

它还考虑了最后一个“dogs”不以空格结尾的情况。

这将删除太多的空格:cats cats cats and dogs dogs dogs and cats cats and dogs dogs 变成了 catsand dogsand catsand dogs。它也匹配了太多:Michael Bolton on CD 变成了 Michael BoltonCD。对于《办公室》的参考,我们表示抱歉。 - Tim Pietzcker
奇怪,我似乎无法重现那些错误。也许我应该添加更多的装饰品:] - C.Evenhuis
1
哎呀,我错了,你是用$1$2替换的,所以我之前认为存在的第一个问题不存在了。但是Michael Bolton仍然有问题。也许一些催眠会有帮助(或者在\w之前加上单词边界\b)。 - Tim Pietzcker

0

请尝试以下代码。



using System;
using System.Text.RegularExpressions;

命名空间 ConsoleApplication1 { /// <summary> ///
/// 正则表达式的描述: ///
/// 匹配表达式但不捕获它。[^|\s+] /// 从2个备选项中选择 /// 行或字符串的开头 /// 空格,一个或多个重复 /// [1]: 编号捕获组。[(\w+)(?:\s+|$)] /// (\w+)(?:\s+|$) /// [2]: 编号捕获组。[\w+] /// 字母数字字符,一个或多个重复 /// 匹配表达式但不捕获它。[\s+|$] /// 从2个备选项中选择 /// 空格,一个或多个重复 /// 行或字符串的结尾 /// [3]: 编号捕获组。[\1|\2],一个或多个重复 /// 从2个备选项中选择 /// 回溯到捕获编号:1 /// 回溯到捕获编号:2 ///
/// /// </summary> class Class1 { /// /// 应用程序的主入口点。 /// static void Main(string[] args) { Regex regex = new Regex( "(?:^|\s+)((\w+)(?:\s+|$))(\1|\2)+", RegexOptions.IgnoreCase | RegexOptions.Compiled ); string str = "cats cats cats and dogs dogs dogs and cats cats and dogs dogs"; string regexReplace = " $1";

Console.WriteLine("Before :" + str);
str = regex.Replace(str,regexReplace);
Console.WriteLine("After :" + str); } }

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接