我有一个大型文本模板,需要用其他文本替换标记化部分。令牌看起来像这样:## USERNAME ##。我的第一个直觉就是使用String.Replace(),但有没有更好,更有效的方法,或者是已经为此优化的Replace()?在大型文本模板中替换标记的最佳方法
回答
System.Text.RegularExpressions.Regex.Replace()是你所寻求的 - 如果你的令牌足够奇怪,你需要一个正则表达式来找到它们。
Some kind soul did some performance testing以及Regex.Replace(),String.Replace()和StringBuilder.Replace()之间,String.Replace()实际上排在最前面。
string.Replace很好。我更喜欢使用正则表达式,但我是***正则表达式。
要记住的是这些模板有多大。如果它真的很大,并且内存是一个问题,那么您可能需要创建一个自定义标记器来处理流。这样,在操作它时,只能将文件的一小部分保存在内存中。
但是,对于耐心的实现,string.Replace应该没问题。
如果您在大型字符串上进行多次替换,那么最好使用StringBuilder.Replace(),因为字符串通常会出现性能问题。
不得不近期做类似的事情。我所做的是:
- 做,需要一个字典的方法(键=标记名称,值=你需要插入文本)
- 获取所有你的令牌格式(##场比赛+#? #在你的情况下,我猜想,在正则表达式中不是那么好:P)使用Regex.Matches(输入,正则表达式)
- foreach结果,使用字典为你的标记查找插入值。
- 返回结果。
做;-)
如果你想测试你的正则表达式我可以建议the regulator.
这是正则表达式的理想使用。查看this helpful website,.Net Regular Expressions class和这本非常有用的书Mastering Regular Expressions。
我不得不这样做的唯一情况是发送一个模板化的电子邮件。在.NET中,开箱即用MailDefinition class提供。因此,这是你如何创建一个模板消息:
MailDefinition md = new MailDefinition();
md.BodyFileName = pathToTemplate;
md.From = "[email protected]";
ListDictionary replacements = new ListDictionary();
replacements.Add("<%To%>", someValue);
// continue adding replacements
MailMessage msg = md.CreateMailMessage("[email protected]", replacements, this);
在此之后,msg.Body将通过模板替换值创建。我想你可以看看MailDefinition.CreateMailMessage()与反射器:)。对不起,有点偏离主题,但如果这是你的情况,我认为这是最简单的方法。
正则表达式是最快的代码解决方案,但如果你有许多不同的令牌,那么它会变慢。如果性能不是问题,则使用此选项。
更好的方法是定义令牌,就像您可以在文本中扫描的“##”一样。然后选择要使用以令牌作为关键字的文本从散列表中替换的内容。
如果这是构建脚本的一部分,那么nAnt有一个很好的功能来做这个叫做Filter Chains。这个代码是开源的,所以你可以看看它是如何完成的快速实现。
那么,取决于你在模板中有多少变量,你有多少模板等,这可能是一个完整的模板处理器的工作。我曾经用过.NET的唯一一个是NVelocity,但我确定其中必须有其他许多人,其中大部分都与某些Web框架或其他框架相关联。
如果你的模板很大,并且你有很多标记,你可能不想走它并逐个替换模板中的标记,因为这会导致O(N * M)操作,其中N是模板的大小和M是要替换的令牌的数量。
以下方法接受您希望替换的键值对的模板和字典。通过将StringBuilder初始化为略大于模板的大小,它应该导致O(N)操作(即它不应该自己增长日志N次)。
最后,您可以将令牌的构建移动到单例中,因为它只需要生成一次。
static string SimpleTemplate(string template, Dictionary<string, string> replacements)
{
// parse the message into an array of tokens
Regex regex = new Regex("(##[^#]+##)");
string[] tokens = regex.Split(template);
// the new message from the tokens
var sb = new StringBuilder((int)((double)template.Length * 1.1));
foreach (string token in tokens)
sb.Append(replacements.ContainsKey(token) ? replacements[token] : token);
return sb.ToString();
}
FastReplacer实现为O令牌替换(N *的log(n)+ m)个时间,并使用3倍原始字符串的存储器中。
当性能很重要时,FastReplacer适用于对大字符串执行许多Replace操作。
主要思想是避免每次更换字符串时修改现有文本或分配新内存。
我们设计了FastReplacer来帮助我们完成一个项目,在这个项目中,我们必须生成一个大量文本,并附加大量的附加和替换操作。使用StringBuilder生成文本的第一个版本的应用程序需要20秒。使用String类的第二个改进版本花了10秒钟。然后我们实现了FastReplacer,持续时间缩短到0.1秒。
- 1. 替换字符串中文本的最佳方法
- 2. 用Python替换大字符串中字符的最佳方法?
- 3. 在几个文件中查找/替换的最佳方法?
- 4. PHP标记替换方法
- 5. 函数模板的typedef的最佳替代方法?
- 6. 在IMAP文件夹中标记消息的最佳方法?
- 7. 在文件中存储大型Python字典的最佳方法
- 8. 替换MSSQL中标记内的文本
- 9. 由$ {varName}表示法在html模板中的文本替换
- 10. 用列文本替换文本标记
- 11. 组织大型ASP.NET MVC2项目中文件的最佳方法?
- 12. 在xml中用值替换占位符的最佳方法
- 13. 在vim中创建替换宏的最佳方法
- 14. 删除用户相关模型记录的最佳方法
- 15. 使用CSS替换文本的最佳方式
- 16. 从大型xml文件中提取大型xml块的最佳方法
- 17. 在大型数据库表中标记重复记录的最快方法
- 18. Laravel中的大型模型的最佳做法
- 19. jQuery替换标记的文本
- 20. 在黑莓上显示大量文本的最佳方法
- 21. 将大量标记文字国际化的最佳做法?
- 22. 用块替换委托方法的最佳方法
- 23. 在asp.net中级联编辑器模板的最佳方法mvc
- 24. 在模板中定义常数值的最佳方法
- 25. 在Python中存储和使用大型文本文件的最佳方式
- 26. 解析HTML文档并替换整个标签片段的最佳方法
- 27. 数据库模型 - SQL - 最佳方法
- 28. 最有效的方法来替换XML流中的文本
- 29. 在ASP.NET中的大型网站上控制页面标题的最佳方法
- 30. 循环并处理大型(10GB +)文本文件的最佳方法是什么?
我相信他们在PowerShell中做了不适用于C#的测试。 C3与PowerShell有不同的内存管理,并且不会将StringBuilder转换为字符串来替换它中的字符。另一方面,正则表达式和StringBuilder在大块数据上更好地工作 – AaA 2013-04-24 07:38:49
RegEx是对大量文本进行替换的可怕选项。尽管功能强大,许多RegEx支持者将整个世界视为钉子和RegEx作为他们的锤子。对于涉及大量文本的用例,请看FastReplacer http://stackoverflow.com/a/11442008/141172 – 2014-11-05 17:57:05