簡體   English   中英

在大文本模板中替換令牌的最佳方法

[英]Best way to replace tokens in a large text template

我有一個很大的文本模板,需要將標記化的部分替換為其他文本。 令牌看起來像這樣:## USERNAME ##。 我的第一個本能只是使用String.Replace(),但是有沒有更好,更有效的方法,或者Replace()已經為此進行了優化?

System.Text.RegularExpressions.Regex.Replace()是您要尋找的-如果您的令牌很奇怪,以至於您需要使用正則表達式來查找它們。

某種善良的人進行了一些性能測試 ,並且在Regex.Replace(),String.Replace()和StringBuilder.Replace()和String.Replace()之間居於首位。

我必須要做的唯一情況是發送模板電子郵件。 在.NET中, MailDefinition類提供了開箱即用的功能 因此,這是創建模板消息的方式:

MailDefinition md = new MailDefinition();
md.BodyFileName = pathToTemplate;
md.From = "test@somedomain.com";

ListDictionary replacements = new ListDictionary();
replacements.Add("<%To%>", someValue);
// continue adding replacements

MailMessage msg = md.CreateMailMessage("test@someotherdomain.com", replacements, this);

此后,將通過替換模板中的值來創建msg.Body。 我想你可以看看帶有Reflector的MailDefinition.CreateMailMessage()。 抱歉,我的話題有點偏離,但是如果您的情況如此,我認為這是最簡單的方法。

好吧,這取決於模板中有多少變量,模板有多少等,這可能是完整模板處理器的工作。 我曾經用於.NET的唯一工具是NVelocity ,但是我敢肯定那里肯定有很多其他工具,其中大多數都鏈接到某個Web框架或另一個Web框架。

FastReplacer在O(n * log(n)+ m)的時間內實現令牌替換,並使用原始字符串內存的3倍。

當性能很重要時,FastReplacer非常適合在大型字符串上執行許多替換操作。

主要思想是避免每次替換字符串時修改現有文本或分配新的內存。

我們設計了FastReplacer來幫助我們處理一個項目,在該項目中我們不得不生成帶有大量追加和替換操作的大文本。 該應用程序的第一個版本使用StringBuilder花費了20秒來生成文本。 使用String類的第二個改進版本花費了10秒。 然后,我們實現了FastReplacer,並將持續時間降至0.1秒。

string.Replace很好。 我更喜歡使用正則表達式,但是對於正則表達式我是***。

要記住的是這些模板的大小。 如果確實很大,並且內存是個問題,則可能要創建一個對流進行操作的自定義標記生成器。 這樣,您在操作文件時只將其一小部分保存在內存中。

但是,對於幼稚的實現,string.Replace應該很好。

如果要對大字符串進行多次替換,則最好使用StringBuilder.Replace(),因為通常會出現字符串性能問題。

最近不得不做類似的事情。 我所做的是:

  • 制作一個需要字典的方法(鍵=令牌名稱,值=您需要插入的文本)
  • 使用Regex.Matches(輸入,正則表達式)獲取與您的令牌格式(我猜是##。+?##的所有匹配項,對正則表達式:P不太好)
  • 使用字典查找結果,以查找令牌的插入值。
  • 返回結果。

完成;-)

如果您想測試您的正則表達式,我可以建議調節器。

正則表達式將是最快的編碼解決方案,但是如果您有許多不同的標記,那么它將變得更慢。 如果性能不是問題,請使用此選項。

更好的方法是定義令牌,例如可以在文本中掃描的“ ##”。 然后從哈希表中選擇要替換的內容,並以令牌后的文本作為鍵。

如果這是構建腳本的一部分,則nAnt具有一個很棒的功能,稱為“ 過濾鏈” 該代碼是開源的,因此您可以查看如何實現快速實現。

如果您的模板很大並且有很多令牌,那么您可能不想遍歷它,並一一替換令牌,因為那樣會導致O(N * M)操作,其中N是模板,M是要替換的令牌數。

以下方法接受您要替換的鍵值對的模板和字典。 通過將StringBuilder初始化為略大於模板的大小,它應該導致O(N)操作(即,它不必將自身增長N次)。

最后,您可以將標記的構建移動到Singleton中,因為只需生成一次即可。

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();
}

這是正則表達式的理想用法。 請訪問此有用的網站.Net正則表達式類以及這本非常有用的書“ 掌握正則表達式”

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM