C# 基于用户的字符串模板

C# 基于用户的字符串模板,c#,C#,我有一个用户选择的字符串模板,我需要使用该模板并填写所需的信息 string templateString = "%author% - %title% (%year%)"; 我可以使用.Contains()和.Replace(),但是模板可能有大量输入或少量输入,例如: string templateString = "%author% - %publisher% - %isbn% - %asin% - %title% (%year%)"; 因此,要执行.Contains()和.Replac

我有一个用户选择的字符串模板,我需要使用该模板并填写所需的信息

string templateString = "%author% - %title% (%year%)";
我可以使用.Contains()和.Replace(),但是模板可能有大量输入或少量输入,例如:

string templateString = "%author% - %publisher% - %isbn% - %asin% - %title% (%year%)";
因此,要执行.Contains()和.Replace(),用户可以选择的每个选项似乎都效率低下,我希望找到一种更好的方法,用请求的信息填充templateString。任何帮助都将不胜感激。这将用于数千件物品


无论用户输入多少文件(电子书,我们中的一些人有数千个),程序本身都会接收这些文件,并根据每个用户的模板对每本电子书进行重命名,用从电子书中刮取的元数据填充信息。

我过去也这样做过。我没有使用
.Contains
而是对每个可用选项调用
.Replace(pattern,replacement)
。在典型的面向用户(如数据显示/输入)的应用程序中,用户永远不会注意到任何减速

在尝试优化性能之前,您确实应该确认您存在性能问题。你很可能是在浪费时间

测试数据: 使用下面的测试代码,您可以看到在25000本“书”中替换10个值需要不到2秒的时间,其中大部分是由写入控制台引起的(如果删除console.WriteLine()并只将书添加到
列表()
,运行时将下降到160ms以下)。我似乎很能接受

String template = @"%index%.  %title% - %author% [%isbn%] - %year%";
            Dictionary<String, String> values = new Dictionary<String, String> { { "title", "A day in the life of..." }, { "author", "Joe S. Schmoe" }, { "year", "1945" }, { "isbn", "987-987-987-987-987" }, { "one", "1" }, { "two", "2" }, { "three", "3" }, { "four", "4" }, { "five", "5" }, { "six", "6" }, { "seven", "7" } };
            String output = string.Empty;
            Stopwatch watch = new Stopwatch();

            watch.Start();
            for (Int32 index = 0; index < 25000; index++) {
                output = template;
                foreach (String key in values.Keys) {
                    output = output.Replace("%" + key + "%", values[key]);
                }
                output = output.Replace("%index%", index.ToString());
                Console.WriteLine(output);
            }
            watch.Stop();

            Console.WriteLine("Elapsed time (ms): " + watch.ElapsedMilliseconds.ToString());
String template=@“%index%.%title%-%author%[%isbn%]-%year%”;
字典价值=新字典{{“标题”,“生命中的一天…”,{“作者”,“乔·S·施莫伊”},{“年”,“1945”},{“isbn”,“987-987-987-987”},{“一”,“一”,“二”,“二”,“三”,“三”,“四”,“四”,“五”,“五”,“六”,“六”,“七”,“七”};
字符串输出=String.Empty;
秒表=新秒表();
watch.Start();
对于(Int32索引=0;索引<25000;索引++){
输出=模板;
foreach(值中的字符串键。键){
输出=输出。替换(“%”+键+“%”,值[键];
}
output=output.Replace(“%index%”,index.ToString());
控制台写入线(输出);
}
看,停;
WriteLine(“经过的时间(毫秒):”+watch.elapsedmillesons.ToString());

我在其他地方发布了这篇文章,但在您的情况下,这似乎是一个很好的方法(我自己也做过)。基本上使用正则表达式替换为匹配计算器回调:

regex = new Regex(@"\%(?<value>.*?)\%", 
    RegexOptions.CultureInvariant | RegexOptions.ExplicitCapture);

string replacedText = regex.Replace(<text>, 
    new MatchEvaluator(this.EvaluateMatchCallback));

其中,
GetReplacementTextBasedOnTemplateValue
是一种方法,它将返回与正则表达式匹配的占位符对应的任何值。

使用简单的
xml
是否有问题?输入看起来如何?是否可以使用正则表达式。使用匹配计算器替换用户是否可以选择完全可自定义的值格式,或来自您已经定义的列表?完全可自定义,只要它是电子书中使用的元数据项。我可能应该在我的原始帖子中包含此项,但这将用于数千项。同意,不管你怎么做,这看起来都很混乱。你能确切地解释一下你在做什么吗?这个程序本身接受了用户输入的多少文件(电子书,我们中的一些人有数千个),并根据每个用户的模板重命名每本电子书,用从电子书中抓取的元数据填充信息。在某些情况下,这比暴力匹配更有效。如果只有在遇到匹配时才运行冗长的过程,那么这是一件好事
private string EvaluateMatchCallback(Match match) {
    string templateInsert = match.Groups["value"].Value;
    // or whatever
    string replacedText = GetReplacementTextBasedOnTemplateValue(templateInsert);
    return replacedText;
}