2012-04-30 16 views
78

Estoy tratando de obtener el número de apariciones de cierto carácter como & en la siguiente cadena.Número de apariciones de un carácter en una cadena

string test = "key1=value1&key2=value2&key3=value3"; 

¿Cómo determino que hay 2 símbolos de unión (&) en la variable de cadena prueba anterior?

+4

¿Por qué regex ?????? – CodesInChaos

+2

@CodeInChaos Porque algunas personas, cuando se enfrentan con un problema, piensan "Lo sé, usaré expresiones regulares". – Tanzelax

+0

@Tanzelax. [Como este] (http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags)? **: -) ** – gdoron

Respuesta

189

usted puede hacer esto :

int count = test.Split('&').Length - 1; 

O con LINQ:

test.Count(x => x == '&'); 
+4

Vale la pena señalar que el primer enfoque podría ser increíblemente caro, si la cadena es grande. En el peor de los casos, si la cadena es grande y (casi) está formada por delimitadores repetidos (&), podría asignar 12-24x al tamaño original de la cadena debido a los gastos generales de los objetos en .Net. Me gustaría ir con el segundo enfoque, y si eso no es lo suficientemente rápido, escriba un bucle for. –

9

Por qué usar regex para eso. String implementa IEnumerable<char>, por lo que solo puede usar LINQ.

test.Count(c => c == '&') 
22

Debido LINQ puede hacer todo ...:

string test = "key1=value1&key2=value2&key3=value3"; 
var count = test.Where(x => x == '&').Count(); 

O si lo desea, puede utilizar la sobrecarga de Count que tiene un predicado:

var count = test.Count(x => x == '&'); 
+0

LINQ también es * más lento * al hacer todo. [Consulte esta página web para conocer los puntos de referencia] (http://blogs.davelozinski.com/curiousconsultant/csharp-net-fastest-way-to-check-if-a-string-occurs-within-a-string) si lo desea * código * rápido. –

+0

@ FreeCoder24 eso no es un problema de LINQ, sino un mal compilador. P.ej. el ejemplo debe estar alineado a un bucle simple * (como lo hace en C++ y Haskell) *. –

+0

@ FreeCoder24, al igual que C# es más lento que Assembly en todo. Si quiere el código _fast_, use Assembly. Y por cierto, LINQ es más rápido en la clasificación que los métodos de framework "nativos". – gdoron

12

El más sencillo y más eficiente, sería simplemente bucle a través de los caracteres en la cadena:

int cnt = 0; 
foreach (char c in test) { 
    if (c == '&') cnt++; 
} 

Usted puede utilizar extensiones de Linq para hacer una simple y casi tan eficiente versión. Hay un poco más arriba, pero sigue siendo sorprendentemente cerca al bucle en el rendimiento:

int cnt = test.Count(c => c == '&'); 

Luego está la vieja Replace truco, sin embargo, que es más adecuado para los idiomas en los bucles es torpe (SQL) o lenta (VBScript):

int cnt = test.Length - test.Replace("&", "").Length; 
+0

_ sorprendentemente cerca del ciclo de rendimiento_ solo con pajares más bien pequeños. – TaW

+0

@TaW: No veo una diferencia de velocidad significativa entre las cadenas cortas y largas (1 MB), pero por alguna razón hay una mayor diferencia en el modo x64 que en el modo x86. – Guffa

+0

No probé la versión de recuento de caracteres, pero el conteo de cadenas de linq se ralentiza cada vez más con cadenas más largas y finalmente muere con una excepción de orden. 1 MB aún no es un problema. – TaW

8

Su ejemplo de cadena se parece a la parte de cadena de consulta de un GET. Si es así, tenga en cuenta que HttpContext tiene un poco de ayuda para usted

int numberOfArgs = HttpContext.Current.QueryString.Count; 

Para obtener más de lo que puede hacer con cadena de consulta, véase NameValueCollection

7

Aquí es la forma más eficiente para obtener el recuento de todas las respuestas. Pero obtendrá un diccionario que contiene pares clave-valor como bonificación.

string test = "key1=value1&key2=value2&key3=value3"; 

var keyValues = Regex.Matches(test, @"([\w\d]+)=([\w\d]+)[&$]*") 
        .Cast<Match>() 
        .ToDictionary(m => m.Groups[1].Value, m => m.Groups[2].Value); 

var count = keyValues.Count - 1; 
+8

jaja, "forma más ineficiente", me encanta! – payo

+1

Pon esto como un Q & A etiquetado 'code-trolling' en http://codegolf.stackexchange.com – Kroltan

Cuestiones relacionadas