有没有更好的方法来计算字符串格式的占位符的字符串在C#中?字符串、方法来、格式

2023-09-04 00:26:04 作者:心也会游荡人也会死亡

我有一个模板字符串和那来自不同的来源,但需要匹配起来创建一个新的填写的字符串参数数组:

I have a template string and an array of parameters that come from different sources but need to be matched up to create a new "filled-in" string:

string templateString = GetTemplate();   // e.g. "Mr {0} has a {1}"
string[] dataItems = GetDataItems();     // e.g. ["Jones", "ceiling cat"}

string resultingString = String.Format(templateString, dataItems);
// e.g. "Mr Jones has a ceiling cat"

通过这个code,我假设的字符串格式占位符模板中的数量将等于数据项的数量。它通常在我的情况下,一个公平的假设,但我希望能够产生 resultingString 没有失败,即使假设是错误的。如果有丢失数据的空白空间,我不介意。

With this code, I'm assuming that the number of string format placeholders in the template will equal the number of data items. It's generally a fair assumption in my case, but I want to be able to produce a resultingString without failing even if the assumption is wrong. I don't mind if there are empty spaces for missing data.

如果有在 dataItems 太多项目,在的String.Format 方法精细处理它。如果没有足够的,我得到一个例外。

If there are too many items in dataItems, the String.Format method handles it fine. If there aren't enough, I get an Exception.

要解决这个问题,我就指望占位符的数量,并增加新的项目到dataItems数组,如果没有足够的。

To overcome this, I'm counting the number of placeholders and adding new items to the dataItems array if there aren't enough.

要算占位符,在code,我与目前的工作是:

To count the placeholders, the code I'm working with at the moment is:

private static int CountOccurrences(string haystack)
{
    // Loop through all instances of the string "}".
    int count = 0;
    int i = 0;
    while ((i = text.IndexOf("}", i)) != -1)
    {
        i++;
        count++;
    }
    return count;
}

显然,这使得有没有未使用的格式的任何占位符右大括号的假设。这也正好的感觉的错误。 :)

有没有更好的方法来计算的字符串格式占位符字符串?

一个多的人正确地指出,我的答案标记为正确不会在许多情况下工作。其主要原因是:

A number of people have correctly pointed out that the answer I marked as correct won't work in many circumstances. The main reasons are:

的正则表达式的计算占位符的数量不占字面括号( {{0}} ) 在计数占位符不考虑重复或跳过占位符(如{0}具有{1},它也有一个{1}) Regexes that count the number of placeholders doesn't account for literal braces ( {{0}} ) Counting placeholders doesn't account for repeated or skipped placeholders (e.g. "{0} has a {1} which also has a {1}")

推荐答案

合并Damovisa的和乔的回答。 我已经更新了答案AFER Aydsman的NAD禾的评论。

Merging Damovisa's and Joe's answers. I've updated answer afer Aydsman's nad activa's comments.

int count = Regex.Matches(templateString, @"(?<!\{)\{([0-9]+).*?\}(?!})")  //select all placeholders - placeholder ID as separate group
                 .Cast<Match>() // cast MatchCollection to IEnumerable<Match>, so we can use Linq
                 .Max(m => int.Parse(m.Groups[1].Value)) + 1; // select maximum value of first group (it's a placegolder ID) converted to int

此方法将适用于像模板:

This approach will work for templates like:

{0} AA {2} BB {1}=>计数= 3

"{0} aa {2} bb {1}" => count = 3

{4} AA {0} BB {0} {0}=>计数= 5

"{4} aa {0} bb {0}, {0}" => count = 5

{0} {3},{{7}}=>数= 4

"{0} {3} , {{7}}" => count = 4