2012-04-30 17 views
78

Sto cercando di ottenere il numero di occorrenze di un determinato carattere come & nella stringa seguente.Numero di occorrenze di un carattere in una stringa

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

Come faccio a determinare che ci sono 2 e commerciali (&) nella variabile stringa di prova di cui sopra?

+4

Perché regex ?????? – CodesInChaos

+2

@CodeInChaos Perché alcune persone, di fronte a un problema, pensano "lo so, userò le espressioni regolari". – Tanzelax

+0

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

risposta

189

si potrebbe fare questo :

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

O con LINQ:

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

Vale la pena notare che il primo approccio potrebbe essere incredibilmente costoso, se la stringa è grande. Nel peggiore dei casi se la stringa è grande e (quasi) interamente composta da delimitatori ripetuti (&), potrebbe allocare 12-24 volte la dimensione originale della stringa a causa dei sovraccarichi degli oggetti in .Net. Vorrei andare con il secondo approccio, e se non è abbastanza veloce quindi scrivere un ciclo for. –

9

Perché utilizzare espressioni regolari per quello. String implementa IEnumerable<char>, quindi è sufficiente utilizzare LINQ.

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

Perché LINQ può fare tutto ...:

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

O se gradite, è possibile utilizzare il Count overload che accetta un predicato:

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

LINQ è anche * più lento * a fare tutto. [Dai un'occhiata a questa pagina web per i benchmark] (http://blogs.davelozinski.com/curiousconsultant/csharp-net-fastest-way-to-check-if-a-string-occurs-within-a-string) se vuoi * codice veloce *. –

+0

@ FreeCoder24 non è un problema di LINQ, ma piuttosto un cattivo compilatore. Per esempio. l'esempio dovrebbe essere inserito in un semplice ciclo * (come in C++ e Haskell) *. –

+0

@ FreeCoder24, proprio come C# è più lento di Assembly in tutto. Se vuoi _fast_ code, usa Assembly. E BTW, LINQ è più veloce nell'ordinamento rispetto ai metodi di framework "nativi". – gdoron

12

Il più semplice e più efficiente, sarebbe semplicemente un ciclo tra i caratteri della stringa:

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

È possibile utilizzare le estensioni Linq per fare un semplice e quasi come versione efficiente. C'è un po 'più in alto, ma è ancora sorprendentemente vicino al circuito in termini di prestazioni:

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

poi c'è il vecchio Replace trucco, tuttavia, che è più adatto per le lingue in cui il ciclo è imbarazzante (SQL) o lento (VBScript):

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

_ sorprendentemente vicino al loop in performance_ solo con mucchi di fieno piuttosto piccoli. – TaW

+0

@TaW: Non vedo una significativa differenza di velocità tra stringhe corte e lunghe (1 MB), ma per qualche motivo c'è una differenza maggiore nella modalità x64 rispetto alla modalità x86. – Guffa

+0

Non ho provato la versione conteggio dei caratteri, ma il conteggio delle stringhe di linq rallenta sempre di più con stringhe più lunghe e alla fine muore con un'eccezione oom. 1 MB non è ancora un problema. – TaW

8

L'esempio di stringa sembra la parte stringa di query di un GET. Se è così, notare che HttpContext ha qualche aiuto per voi

int numberOfArgs = HttpContext.Current.QueryString.Count; 

Per più di quello che si può fare con QueryString, vedere NameValueCollection

7

Ecco il modo più inefficiente per ottenere il conteggio di tutte le risposte. Ma otterrai un dizionario che contiene coppie di valori-chiave come bonus.

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

haha, "il modo più inefficiente", lo adoro! – payo

+1

Metti questo come un 'code-trolling 'di codice Q & A su http://codegolf.stackexchange.com – Kroltan

Problemi correlati