2010-06-10 63 views
5

Supposons que j'ai eu une chaîne, "chats chats chats et chiens chiens chiens."Comment se débarrasser des doublons dans regex

Quelle expression régulière utiliserais-je pour remplacer cette chaîne par «chats et chiens»? c'est-à-dire supprimer les doublons. L'expression ne doit cependant supprimer que les doublons qui se suivent. Par exemple:

« chats chats chats et chiens chiens chiens et chats chats et chiens chiens »

renverrait:

« les chats et les chiens et les chats et les chiens »

+0

Check out http://stackoverflow.com/questions/1058783/regular-expression-to-find-and-remove-duplicate-words il pourrait vous donner quelques indications sur ta question. –

Répondre

2

Replace (\w+)\s+\1 avec $1

Effectuez cette opération en boucle jusqu'à ce que plus aucune correspondance ne soit trouvée. Définition de l'indicateur global ne suffit pas car il ne remplacerait pas le troisième cats dans cats cats cats

\1 dans regex fait référence au contenu du premier groupe capturé.

Essayez:

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); 
+0

J'utilise ce code: replacer = Regex.Replace (remplaceur, @ "([\\ n] +) [\ s +]? \ 1", string.Empty); mais cela ne semble pas fonctionner. Cela fonctionne dans les rubriques http://www.rubular.com/r/Ey6wrLYXNw –

+0

@Emmanuel Essayez 'str = Regex.Replace (str, @" (\ w +) \ s + \ 1 "," $ 1 ");' – Amarghosh

+0

Pourquoi cela a-t-il été voté? – Amarghosh

1

Sans doute, il y a une plus petite regex possible, mais celui-ci semble faire l'affaire:

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"); 

Il prend également en compte les derniers « chiens » ne se termine pas avec un espace.

+0

Cela va supprimer trop d'espaces: «chats chats et chiens chiens chiens et chats chats et chiens chiens» devient «chats et chiens et chats et chiens». Cela correspond aussi trop: «Michael Bolton sur CD» devient «Michael BoltonCD». Désolé pour la référence Office Space. –

+0

Bizarre, je n'arrive pas à reproduire ces erreurs. Peut-être que je devrais ajouter quelques morceaux de flair:] –

+1

Oups, j'ai raté que vous remplacez par "$ 1 $ 2", de sorte que le premier problème que je pensais avoir vu n'est pas là. Mais Michael Bolton a toujours un problème. Peut-être que l'hypnose aidera (ou une limite de mot '\ b' avant le' \ w'). –

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

effectuera tous les remplacements en un seul appel.

Explication:

\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 
+0

Tim, vous êtes un gourou regex. Le respect! :) – Koen

+0

+1, parce que l'expression fonctionne et de plus il est expliqué. –

0

Essayez le code suivant.



using System; 
using System.Text.RegularExpressions;

namespace ConsoleApplication1 { /// <summary> ///
/// A description of the regular expression: ///
/// Match expression but don't capture it. [^|\s+] /// Select from 2 alternatives /// Beginning of line or string /// Whitespace, one or more repetitions /// [1]: A numbered capture group. [(\w+)(?:\s+|$)] /// (\w+)(?:\s+|$) /// [2]: A numbered capture group. [\w+] /// Alphanumeric, one or more repetitions /// Match expression but don't capture it. [\s+|$] /// Select from 2 alternatives /// Whitespace, one or more repetitions /// End of line or string /// [3]: A numbered capture group. [\1|\2], one or more repetitions /// Select from 2 alternatives /// Backreference to capture number: 1 /// Backreference to capture number: 2 ///
/// /// </summary> class Class1 { /// /// Point d'entrée principal de l'application. /// 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); } }

}

Questions connexes