2017-02-16 2 views
0

Gibt es eine Funktion zum Abfragen der erwarteten Eingaben und Formate aus einer Formatzeichenfolge - d. H. Eine, die als erstes Argument für die Funktion String.Format vorgesehen ist?String.Format - Abfrage von Metadaten aus der Formatzeichenfolge

z.B. gegeben:

"On {0:yyyyy-MM-dd} do {1} and earn {2:C2}" 

Ich möchte wie etwas zurück zu bekommen:

{"yyyyy-MM-dd", null, "C2"} 

ich eine Regex eine Möglichkeit erraten ist, aber es precanned etwas, dass Haken in die gleiche Logik wie String.Format?

+1

Haben Sie [FormattableString] (https://msdn.microsoft.com/en-us/library/system.formattablestring (v = vs.110) .aspx) überprüft, insbesondere ist es [GetArguments] (https://msdn.microsoft.com/en-us/library/system.formattablestring.getarguments(v=vs.110).aspx) Methode. Ich weiß nicht, ob das tun wird, was du brauchst, aber es könnte ein Anfang sein ...? –

+0

@RB. das ist nur für interpolierte Strings, die * nicht ohne ihre Argumente erscheinen können. Es besteht keine Notwendigkeit, die * Platzhalter * in diesem Fall abzurufen. –

+1

@Geoff_h was versuchst du zu tun? String.Format selbst * analysiert * die Formatzeichenfolge nicht. Es ruft schließlich die interne Methode [StringBuilder.AppendFormatHelper] (https://referencesource.microsoft.com/#mscorlib/system/text/stringbuilder.cs2c3b4c2e7c43f5a4) auf, die die Formatzeichenfolgen nur als Zeichenfolgen mit Trennzeichen behandelt. Es versucht nicht, sie zu parsen. Das Format wird direkt an die Methode 'ToString()' jedes Argumenttyps übergeben. –

Antwort

1

String.Format sich die Formatzeichenfolge nicht analysieren. Es ruft schließlich die interne StringBuilder.AppendFormatHelper-Methode auf, die die Formatzeichenfolgen nur als Zeichenfolgen mit Trennzeichen behandelt. Es versucht nicht, sie zu parsen. Das Format wird direkt an die Formatierungsmethode jedes Argumenttyps übergeben. Die Leistung der Zeichenfolgenformatierung ist sowohl für die Laufzeit als auch für die Anwendungen von entscheidender Bedeutung.

Sie können einen regulären Ausdruck verwenden, um die Formatzeichenfolge zu analysieren. Sie müssen auf geschweifte Klammern ({{, {}) und Ausrichtungszeichenfolgen achten.

Die Regex {(?<index>\d+)(,(?<algn>-?\d+?))?(:(?<fmt>.*?))?} extrahiert die Index-, Alignment- und Formatsegmente als benannte Gruppen. Ausgebürstete Klammern * werden explizit nicht behandelt. Es wird vermieden, {{ {} aber nicht {{2,20:N{}:

var regex=new System.Text.RegularExpressions.Regex(@"{(?<index>\d+)(,(?<algn>-?\d+?))?(:(?<fmt>.*?))?}"); 
var matches=regex.Matches("asdf{0:d2} {1:yyyy-MM-dd} {2,-20:N2}"); 
foreach(Match match in matches) 
{ 
    Console.WriteLine("{0,-5} {1,-15} {2,-15}", 
         match.Groups["index"].Value, 
         match.Groups["algn"].Value, 
         match.Groups["fmt"].Value); 
} 

Dies wird zurück:

0    d2    
1    yyyy-MM-dd  
2  -20  N2    

Die (?<name>...) Syntax fängt ein Muster und legt es als eine benannte Gruppe. erfasst eine Ziffernfolge und macht sie als Gruppe index verfügbar.

Die ? in .*? gibt eine nicht gierige Übereinstimmung an. Normalerweise ist eine Regex gierig - sie erfasst so viele Zeichen wie möglich. Wenn Sie .*? verwenden, erfasst die Regex so wenig Zeichen wie möglich, bevor das nächste Muster beginnt. Deshalb stoppt die optionale Gruppe algn bei :.

0

Wahrscheinlichkeiten sind keine Standardmittel dafür. Verwendung Regex, ist es einfach:

var args = new List<string>(); 
var str = "On {0:yyyyy-MM-dd} do {1} and earn {2:C2}"; 
MatchCollection matches = Regex.Matches(str, @"\{\d+[^\{\}]*\}"); 
foreach (Match match in matches) 
{ 
    string obj = null; 
    var split = match.ToString().Split(':'); 
    if (split.Length == 2) obj = split.Last().Trim(' ', '}', '{'); 
    args.Add(obj); 
} 

// Result: args = {"yyyyy-MM-dd", null, "C2"} 
+0

Diese Regex funktioniert jedoch nicht. Eine gute Regex erfordert keine zusätzliche Aufteilung. Diese Regex kümmert sich auch nicht um die vollständige Formatzeichenfolgenspezifikation mit Ausrichtungs- und Längenspezifikationen. –

+0

Es ist Regex Arbeit für mich richtig. –

+0

Du musst * danach splitten und trimmen *. Es wird auch nicht mit der Ausrichtung umgehen –