2010-01-28 5 views
9

Avant d'utiliser String.Format pour formater une chaîne en C#, j'aimerais savoir combien de paramètres cette chaîne accepte-t-elle?La chaîne a combien de paramètres

Par exemple. si la chaîne était "{0} n'est pas la même que {1}", je voudrais savoir que cette chaîne accepte deux paramètres Par exemple. si la chaîne était "{0} n'est pas la même chose que {1} et {2}", la chaîne accepte 3 paramètres

Comment puis-je trouver ceci efficacement?

+0

Ce n'est pas facile. Qu'est-ce que vous essayez d'accomplir? Il y a presque certainement une meilleure façon de s'y prendre. – Auraseer

Répondre

6

String.Format reçoit un argument de chaîne avec la valeur format et un tableau params object[], qui peut gérer des éléments de grande valeur arbitraires.

Pour chaque valeur object, il est la méthode .ToString() sera appelée à résoudre ce modèle de format

EDIT: Semble J'ai mal lu votre question. Si vous voulez savoir combien d'arguments sont nécessaires à votre format, vous pouvez découvrir qu'en utilisant une expression régulière:

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 

Comme Benjamin noté dans les commentaires, peut-être vous avez besoin de savoir nombre de différentes références. Si vous ne LINQ, ici vous allez:

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 

Cette adresse également @280Z28 dernier problème repéré.

Modifier par 280Z28: Ce ne sera pas valider l'entrée, mais pour une entrée valide donnera la bonne réponse:

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

La vôtre n'attrape pas "Échec: {0} {{{1}}}" 'ou" Échec: {0} ({0}) "'. –

+0

Et l'OP veut connaître le nombre d'objets à passer à l'appel, afaik - donc il n'a pas besoin du nombre de références mais du nombre de références différentes. "{0} {0} {1}" compterait probablement comme "2" dans son monde. C'est très facile de votre expression cependant. Agréable. –

+0

@Rubens: Oui, vous avez le premier mais pas le second. Vous devez analyser les correspondances en entier et prendre le maximum plus 1. En voici une autre valide: '" {2} "' (trois paramètres, mais une seule substitution). –

1

Vous devrez analyser la chaîne et trouver la valeur entière la plus élevée entre les {} ... puis en ajouter une.

... ou de compter le nombre de jeux de {}.

De toute façon, c'est moche. Je serais intéressé de savoir pourquoi vous devez être en mesure de trouver ce numéro par programme.

EDIT

Comme mentionné 280Z28, vous devrez prendre en compte les différentes particularités de ce qui peut être compris entre les {} 's (plusieurs {}' s, le formatage des chaînes, etc.).

+2

Mais rappelez-vous que '{{Tricky}}' peut apparaître, tout comme '{0: 0000}'. –

+0

alors, pourquoi ai-je besoin de ça? Je travaille avec des documents OpenXML où les requêtes xpath sont placées à l'intérieur d'une partie xml personnalisée de documents Word. Dans mon code, j'ai besoin de remplacer les paramètres dans la requête xpath par des valeurs basées sur le contexte de ce xpath. Le nombre de paramètres dans les différents xpaths du document variera donc si je peux trouver le nombre de paramètres que la chaîne accepte, je peux utiliser un if-else basé sur cela pour effectuer la chaîne correcte.Format J'espère que j'ai expliqué cela clairement. –

+0

Fondamentalement, vous devez implémenter vous-même la première moitié du 'StringBuilder.AppendFormat (fournisseur IFormatProvider, format de chaîne, arguments params [] args)' implémentation de la méthode (~ 75 lignes de code) pour gérer toutes les idiosyncrasies. –

1

Je compte sur ReSharper pour analyser cela pour moi, et il est dommage que Visual Studio ne livre pas avec une telle fonctionnalité.

Questions connexes