2012-07-19 19 views
5

Estoy buscando una manera elegante, preferiblemente una expresión de linq corta, para contar cuántos caracteres de caracteres alfanuméricos contiene una cadena dada.¿Manera elegante de contar caracteres alfanuméricos en una cadena?

La forma 'aburrido' lo hago ahora es la siguiente:

int num = 0; 
for (int i = 0; i < password.Length; i++) 
{ 
    if (!char.IsLetterOrDigit(password, i)) 
    { 
     num++; 
    } 
} 
if (num < MinRequiredNonAlphanumericCharacters) 
    return false; 

Esto es bastante corta ya, pero estoy seguro de que con un poco de magia LINQ esto se puede hacer en una expresión aún más corto, igualmente fácil de entender, ¿derecho?

+0

La forma de linq no se presta también a una muy buena optimización, que es dejar de buscar la cadena una vez que tenga suficientes caracteres alfanuméricos. Bueno, dado el contexto de las contraseñas y su longitud, tal vez no es una optimización 'muy buena' ... – corsiKa

+0

@corsiKa no creo que vaya a la optimización tanto azúcar elegante/azúcar sintáctica ... –

+0

Así es, yo Estoy haciendo hash PBKDF2 justo después de esa parte, por lo que algunos milisegundos aquí no son el problema de todos modos. – magnattic

Respuesta

14

Aquí es la manera rápida y sucia LINQ para obtener la carta & cuenta dígito:

password.Count(char.IsLetterOrDigit) 

Esto es más de una copia directa de lo que está haciendo:

password.Count(c => !char.IsLetterOrDigit(c)) 
+0

Si esto realmente funciona, será difícil de superar en términos de longitud. Bien hecho, señor. – magnattic

0

Puede hacerlo con una línea de Regex. Si eso es comprensible es un punto discutible.

num = new Regex(@"\w", RegexOptions.IgnoreCase).Matches(input).Count 
2
int num = password.Where((t, i) => !char.IsLetterOrDigit(password, i)).Count(); 

if (num < MinRequiredNonAlphanumericCharacters) 
    return false; 
+0

Donde es innecesario aquí ya que puede hacer el mismo control en el Conteo –

+0

@AustinSalonen ya que puede ver varias maneras que ya se han mostrado en esta página como respuestas, personalmente encuentro Dónde fácil de usar, es el primer método de extensión que viene mi mente – HatSoft

0

Puede usar Take() para asegurarse de no inspeccionar más letras de las necesarias:

int minCount = password.Where(x => !char.IsLetterOrDigit(x)).Take(MinRequired).Count(); 
if (minCount < MinRequired) { // No good } 

La idea es que solo sigamos comprobando hasta que haya alcanzado el número mínimo. En ese momento, podemos detenernos, porque sabemos que tenemos una contraseña admisible. Take() toma tantas como puede, y nada más, de modo que si no hay suficientes, simplemente devolverá un número menor al que ha solicitado.

Cuestiones relacionadas