2010-12-13 901 views
11

Tengo un sitio web que permite a los usuarios comentar sobre las fotos. Por supuesto, los usuarios dejan comentarios como:Cómo eliminar caracteres repetidos en una cadena

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

o

'USTED SUCCCCCCCCCCCCCCCCCKKKKKKKKKKKKKKKKKK'

usted lo consigue.

Básicamente, quiero acortar esos comentarios eliminando al menos la mayoría de esos caracteres repetidos en exceso. Estoy seguro de que hay una manera de hacerlo con Regex ... simplemente no puedo resolverlo.

¿Alguna idea?

+5

no creo que esto es una buena solución ... esto cambia la lingüística de la observación de algo que el autor no tenía la intención. Básicamente pretendían idiotez y lo transformarás en un galimatías. Por ejemplo, cuando alguien dice "¡booooo!" ¿Lo transformarás en "bo!" ¿Qué hay de los números? Nombres de usuario? URLs? – tenfour

+4

Usted comienza a acortar de tres leters que se repiten - los letreros doblados son al comon en inglés. – Piskvor

+1

El spam idiote bien tipificado sigue siendo un spam idiota, apenas un poco más difícil de detectar de un vistazo. –

Respuesta

9

Teniendo en cuenta que el idioma Inglés utiliza letras dobles menudo es probable que no quieren eliminar ciegamente ellos. Aquí hay una expresión regular que eliminará cualquier cosa más allá de un doble.

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!!" 
+0

El idioma ruso a veces usa letras triples (varía rara vez), solo para tu información. – AgentFire

+0

Interesante, no lo sabía. Sería genial aumentar la expresión regular para conocer un conjunto de letras que se espera dupliquen o tripliquen y se comporten de manera adecuada. –

8

¿Desea acortar específicamente las cadenas en el código, o sería suficiente simplemente fallar la validación y presentar el formulario nuevamente al usuario con un error de validación? Algo así como "Demasiados caracteres repetidos".

Si este último es aceptable, @"(\w)\1{2}" debe coincidir con los caracteres de 3 o más (interpretados como "repetidos" dos o más veces).

Editar: Como @Piskvor señaló, esto coincidirá exactamente en 3 caracteres. Funciona bien para emparejar, pero no para reemplazar. Su versión, @"(\w)\1{2,}", funcionaría mejor para reemplazar. Sin embargo, me gustaría señalar que creo que reemplazar no sería la mejor práctica aquí. Es mejor que la validación de formularios falle antes que tratar de eliminar el texto que se envía, ya que es probable que existan casos límite en los que el texto que de otra forma sería legible (incluso si no es razonable) no tenga sentido.

+1

'(\ w) \ 1 {2,}', yo diría. '(\ w) \ 1 {2}' coincidiría exactamente con tres caracteres. – Piskvor

+0

@Piskvor: ¿Estás seguro? No soy experto en expresiones regulares de ninguna manera, pero acabo de probar el mío en "abbbbbbbcdef" y coincidió. (Al menos en .NET, que incluso puede exhibir un comportamiento no estándar, pero es el entorno en cuestión). – David

+0

Oh, va a * coincidir * bien (ya que * hay * subcadenas con exactamente tres repeticiones), simplemente no coincidirá con la duplicación completa; tenga en cuenta que solo coincide con la parte en negrita: "a ** bbb ** bbbbcdef". No es del todo conveniente hacer una coincidencia * y reemplazar *. – Piskvor

0

Editar: horrible sugerencia, por favor, no leen, que realmente se merecen mi -1 :)

he encontrado aquí en technical nuggets algo así como lo que estás buscando.

No hay nada que hacer, excepto mucho expresiones regulares, porque nunca he oído hablar de una señal de expresiones regulares para la repetición ...

Es un ejemplo totales, no voy a pegarlo aquí, pero creo que esta voluntad responde totalmente tu pregunta

+1

Aargh, eso es horrible. Ääääääɫɫɫɫśśśśööööööö, esto solo detendrá los personajes incluidos en la lista negra, no del todo útil ahora que Unicode es ampliamente compatible. Lea acerca de las referencias regex: existen, aunque nunca las haya escuchado hasta ahora. – Piskvor

+0

@Piskvor: Sí, estoy tratando de buscarlos, pero no puedo encontrar un lugar donde se explique. De hecho, en el @ "(\ w) \ 1 {2}", no entiendo qué significa \ 1. Si tienes un enlace donde está explicado, eso sería muy útil para mí :) – LaGrandMere

+0

@LaGrandMere: No tengo ningún enlace a mano, pero el '\ 1' básicamente significa que está mirando hacia atrás al primer grupo en la expresión regular (primer set de paréntesis), que es '(\ w)'. – David

0

Distinct() eliminará todos los duplicados, sin embargo, no verá "A" y "a" como el mismo, obviamente.

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

Salidas "asdfa"

0
var test = "OMMMMMGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGMMM"; 

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

expresiones regulares pueden ser excesivos. Prueba esto:

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(); 
    } 
1
var nonRepeatedChars = myString.ToCharArray().Distinct().Where(c => !char.IsWhiteSpace(c) || !myString.Contains(c)).ToString(); 
Cuestiones relacionadas