2010-01-28 16 views
9

Prima di utilizzare String.Format per formattare una stringa in C#, vorrei sapere quanti parametri accetta quella stringa?La stringa ha quanti parametri

Ad es. se la stringa era "{0} non è uguale a {1}", mi piacerebbe sapere che questa stringa accetta due parametri Ad es. se la stringa era "{0} non è uguale a {1} e {2}", la stringa accetta 3 parametri

Come posso trovarlo in modo efficiente?

+0

Questo non è facile. Cosa stai cercando di realizzare? C'è quasi sicuramente un modo migliore per farlo. – Auraseer

risposta

6

String.Format riceve un argomento stringa con il valore format e un array params object[], che può gestire elementi di valore elevato arbitrario.

Per ogni valore object, è .ToString() metodo sarà chiamato a risolvere quel modello formato

EDIT: Sembra ho letto male la tua domanda. Se volete sapere quanti argomenti sono necessari per il formato, si può scoprire che utilizzando un'espressione regolare:

string pattern = "{0} {1:00} {{2}}, Failure: {0}{{{1}}}, Failure: {0} ({0})"; 
int count = Regex.Matches(Regex.Replace(pattern, 
    @"(\{{2}|\}{2})", ""), // removes escaped curly brackets 
    @"\{\d+(?:\:?[^}]*)\}").Count; // returns 6 

Come Benjamin notato nei commenti, forse si ha bisogno di conoscere il numero di differenti riferimenti. Se non si utilizza Linq, qui si va:

int count = Regex.Matches(Regex.Replace(pattern, 
    @"(\{{2}|\}{2})", ""), // removes escaped curly brackets 
    @"\{(\d+)(?:\:?[^}]*)\}").OfType<Match>() 
    .SelectMany(match => match.Groups.OfType<Group>().Skip(1)) 
    .Select(index => Int32.Parse(index.Value)) 
    .Max() + 1; // returns 2 

questo indirizzo anche @280Z28 ultimo problema individuato.

Edit da 280Z28: Questo non convaliderà l'input, ma per qualsiasi input valido darà la risposta corretta:

int count2 = 
    Regex.Matches(
     pattern.Replace("{{", string.Empty), 
     @"\{(\d+)") 
    .OfType<Match>() 
    .Select(match => int.Parse(match.Groups[1].Value)) 
    .Union(Enumerable.Repeat(-1, 1)) 
    .Max() + 1; 
+0

Il tuo non intercetta "" Errore: {0} {{{1}}} "' o "" Errore: {0} ({0}) "'. –

+0

E l'OP vuole conoscere il numero di oggetti da passare alla chiamata, afaik - quindi non ha bisogno del numero di riferimenti ma del numero di riferimenti diversi. "{0} {0} {1}" probabilmente conterebbe come "2" nel suo mondo. Questo è molto facile dalla tua espressione però. Bello. –

+0

@Rubens: Sì, hai ottenuto il primo di essi ma non il secondo. Devi analizzare le corrispondenze di un intero e ottenere il massimo di 1. Ecco un'altra valida: '" {2} "' (tre parametri, ma solo una sostituzione). –

1

Dovrai analizzare la stringa e trovare il valore intero più alto tra lo {} ... quindi aggiungerne uno.

... o contare il numero di serie di {}.

In entrambi i casi, è brutto. Sarei interessato a sapere perché è necessario essere in grado di capire questo numero in modo programmatico.

EDIT

Come 280Z28 accennato, si dovrà tenere conto delle diverse peculiarità di ciò che può essere inclusa tra i 's (più {}' {} s, stringhe di formattazione, etc.).

+2

Ma ricorda che '{{Tricky}}' può apparire, così come '{0: 0000}'. –

+0

quindi, perché ho bisogno di questo? Sto lavorando con documenti OpenXML in cui le query xpath sono posizionate all'interno di una parte personalizzata xml di documenti word. Nel mio codice, ho bisogno di sostituire i parametri all'interno della query xpath con valori basati sul contesto di quel percorso x. Il numero di parametri all'interno dei diversi xpath nel documento sarà variabile, quindi se riesco a trovare il numero di parametri accettati dalla stringa, posso usare un if-else basato su quello per eseguire la stringa corretta.Formato Spero di averlo spiegato chiaramente. –

+0

Fondamentalmente, è necessario implementare te stesso la prima metà di 'StringBuilder.AppendFormat (provider IFormatProvider, formato stringa, oggetto params [] args) implementazione del metodo (~ 75 righe di codice) per gestire tutte le idiosincrasie. –

1

Mi affido a ReSharper per analizzare che per me, ed è un peccato che Visual Studio non viene fornito con una funzionalità così bella.

Problemi correlati