我有一個大型文本模板,需要用其他文本替換標記化部分。令牌看起來像這樣:## 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. 用JSF標記替換c:forEach的最佳方法
- 2. 替換字符串中文本的最佳方法
- 3. 用Python替換大字符串中字符的最佳方法?
- 4. 在幾個文件中查找/替換的最佳方法?
- 5. 在多個文件中替換VBA代碼的最佳方法?
- 6. 在大文件中實現字符串替換的最佳方法?
- 7. PHP標記替換方法
- 8. 函數模板的typedef的最佳替代方法?
- 9. 在IMAP文件夾中標記消息的最佳方法?
- 10. 在文件中存儲大型Python字典的最佳方法
- 11. 替換MSSQL中標記內的文本
- 12. 由$ {varName}表示法在html模板中的文本替換
- 13. 用列文本替換文本標記
- 14. Django字符串串聯內部模板標記最佳做法
- 15. 組織大型ASP.NET MVC2項目中文件的最佳方法?
- 16. 在vim中創建替換宏的最佳方法
- 17. 在xml中用值替換佔位符的最佳方法
- 18. 在XML內容中替換值的最佳方法?
- 19. 刪除用戶相關模型記錄的最佳方法
- 20. 使用CSS替換文本的最佳方式
- 21. 從大型xml文件中提取大型xml塊的最佳方法
- 22. Laravel中的大型模型的最佳做法
- 23. 在大型數據庫表中標記重複記錄的最快方法
- 24. 用塊替換委託方法的最佳方法
- 25. 在黑莓上顯示大量文本的最佳方法
- 26. jQuery替換標記的文本
- 27. 將大量標記文字國際化的最佳做法?
- 28. 在asp.net中級聯編輯器模板的最佳方法mvc
- 29. 在Drupal中集成HTML模板的最佳方法
- 30. 在模板中定義常數值的最佳方法
我相信他們在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