Как удалить повторяющиеся символы в строке

У меня есть веб-сайт, который позволяет пользователям комментировать фотографии. Конечно, пользователи оставляют комментарии, например:

'OMGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG!!!!!!!!!!!!!!!'

или

'YOU SUCCCCCCCCCCCCCCCCCKKKKKKKKKKKKKKKKKK'

Вы его получите.

В принципе, я хочу сократить эти комментарии, удалив по крайней мере большинство этих лишних повторяющихся символов. Я уверен, что есть способ сделать это с помощью Regex.. я просто не могу понять это.

Любые идеи?

Ответ 1

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

Regex r = new Regex("(.)(?<=\\1\\1\\1)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled);

var x = r.Replace("YOU SUCCCCCCCCCCCCCCCCCKKKKKKKKKKKKKKKKKK", String.Empty);
// x = "YOU SUCCKK"

var y = r.Replace("OMGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG!!!!!!!!!!!!!!!", String.Empty);
// y = "OMGG!!"

Ответ 2

Вы специально хотите укоротить строки в коде, или было бы достаточно просто проверить проверку и снова представить форму пользователю с ошибкой проверки? Что-то вроде "Слишком много повторяющихся символов".

Если последнее допустимо, @"(\w)\1{2}" должно соответствовать символам 3 или более (интерпретируется как "повторяется" два или более раз).

Изменить: Как отметил @Piskvor, это будет соответствовать ровно 3 символам. Он отлично подходит для соответствия, но не для замены. Его версия @"(\w)\1{2,}" будет работать лучше для замены. Тем не менее, я хотел бы указать, что, по-моему, замена не будет лучшей практикой здесь. Лучше просто иметь проверку отказов формы, чем пытаться очистить текст, отправляемый, потому что вероятнее всего будут случаи с краем, когда вы превращаете текст, который можно читать (даже если это неразумно) в бессмыслицу.

Ответ 3

Regex будет излишним. Попробуйте следующее:

public static string RemoveRepeatedChars(String input, int maxRepeat)
    {
        if(input.Length==0)return input;

        StringBuilder b = new StringBuilder;
        Char[] chars = input.ToCharArray();
        Char lastChar = chars[0];
        int repeat = 0;
        for(int i=1;i<input.Length;i++){
            if(chars[i]==lastChar && ++repeat<maxRepeat)
            {
                b.Append(chars[i]);
            }
            else
            {
                b.Append(chars[i]);
                repeat=0;
                lastChar = chars[i];
            }
        }
        return b.ToString();
    }

Ответ 4

var nonRepeatedChars = myString.ToCharArray().Distinct().Where(c => !char.IsWhiteSpace(c) || !myString.Contains(c)).ToString();

Ответ 5

Изменить: ужасное предложение, пожалуйста, не читайте, я действительно заслуживаю свой -1:)

Я нашел здесь технические самородки что-то вроде того, что вы ищете.

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

Это общий пример, я не буду вставлять его здесь, но я думаю, что это полностью ответит на ваш вопрос.

Ответ 6

Distinct() удалит все дубликаты, однако он не увидит "A" и "a" как одно и то же, очевидно.

Console.WriteLine(new string("Asdfasdf".Distinct().ToArray()));

Выходы "Asdfa"

Ответ 7

var test = "OMMMMMGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGMMM";

test.Distinct().Select(c => c.ToString()).ToList()
        .ForEach(c =>
            { 
                while (test.Contains(c + c)) 
                test = test.Replace(c + c, c); 
            }
        );