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