3

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

string templateString = "%author% - %title% (%year%)";

我可以使用 .Contains() 和 .Replace(),但是模板可能有大量输入或少量输入,例如:

string templateString = "%author% - %publisher% - %isbn% - %asin% - %title% (%year%)";

因此,为用户可以选择的每个选项执行 .Contains() 和 .Replace() 似乎效率低下,我希望做的是找到一种更好的方法来使用请求的信息填充 templateString。任何帮助将不胜感激。这将用于数千个项目。

无论用户输入多少文件(电子书,我们中的一些人有数千个),该程序本身都会获取许多文件,它会根据个人用户的模板重命名每本电子书,并使用从电子书中抓取的元数据填充信息。

4

2 回答 2

4

我在其他地方发布了这个,但在你的情况下看起来这将是一个很好的方法(我自己也做过)。基本上,您使用正则表达式替换匹配评估器回调:

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

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

然后您的回调将如下所示:

private string EvaluateMatchCallback(Match match) {
    string templateInsert = match.Groups["value"].Value;
    // or whatever
    string replacedText = GetReplacementTextBasedOnTemplateValue(templateInsert);
    return replacedText;
}

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

于 2012-08-16T20:44:20.407 回答
1

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

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

测试数据: 使用下面的测试代码,您可以看到替换 25,000 个“书”中的 10 个值需要不到 2 秒,其中大部分是由写入控制台引起的(如果删除 Console.WriteLine(),运行时间会下降到 160 毫秒以下只需将书籍添加到 a List<String>())。对我来说似乎很容易接受。

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());
于 2012-08-16T20:40:35.537 回答