<p>I have a large text template which needs tokenized sections replaced by other text. The tokens look something like this: ##USERNAME##.  My first instinct is just to use String.Replace(), but is there a better, more efficient way or is Replace() already optimized for this?</p>

[{'answer_id': 20270, 'author': 'Greg Hurlman', 'author_id': 35, 'author_profile': 'https://Stackoverflow.com/users/35', 'pm_score': 5, 'selected': True, 'text': '<p><a href="http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.replace.aspx" rel="noreferrer" title="MSDN">System.Text.RegularExpressions.Regex.Replace()</a> is what you seek - IF your tokens are odd enough that you need a regex to find them.</p>\n\n<p><a href="http://blogs.msdn.com/debuggingtoolbox/archive/2008/04/02/comparing-regex-replace-string-replace-and-stringbuilder-replace-which-has-better-performance.aspx" rel="noreferrer">Some kind soul did some performance testing</a>, and between Regex.Replace(), String.Replace(), and StringBuilder.Replace(), String.Replace() actually came out on top.</p>\n'}, {'answer_id': 20276, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 2, 'selected': False, 'text': "<p>string.Replace is fine.  I'd prefer using a Regex, but I'm *** for regular expressions.  </p>\n\n<p>The thing to keep in mind is how big these templates are.  If its real big, and memory is an issue, you might want to create a custom tokenizer that acts on a stream.  That way you only hold a small part of the file in memory while you manipulate it.  </p>\n\n<p>But, for the naiive implementation, string.Replace should be fine.  </p>\n"}, {'answer_id': 20280, 'author': 'samjudson', 'author_id': 1908, 'author_profile': 'https://Stackoverflow.com/users/1908', 'pm_score': 2, 'selected': False, 'text': '<p>If you are doing multiple replaces on large strings then it might be better to use StringBuilder.Replace(), as the usual performance issues with strings will appear.</p>\n'}, {'answer_id': 20290, 'author': 'Erik van Brakel', 'author_id': 909, 'author_profile': 'https://Stackoverflow.com/users/909', 'pm_score': 2, 'selected': False, 'text': '<p>Had to do something similar recently. What I did was:</p>\n\n<ul>\n<li>make a method that takes a dictionary (key = token name, value = the text you need to insert)</li>\n<li>Get all matches to your token format (##.+?## in your case I guess, not that good at regular expressions :P) using Regex.Matches(input, regular expression)</li>\n<li>foreach over the results, using the dictionary to find the insert value for your token.</li>\n<li>return result.</li>\n</ul>\n\n<p>Done ;-)</p>\n\n<p>If you want to test your regexes I can suggest <a href="http://sourceforge.net/projects/regulator/" rel="nofollow noreferrer">the regulator.</a></p>\n'}, {'answer_id': 20337, 'author': 'Factor Mystic', 'author_id': 1569, 'author_profile': 'https://Stackoverflow.com/users/1569', 'pm_score': 0, 'selected': False, 'text': '<p>This is an ideal use of Regular Expressions. Check out <a href="http://regular-expressions.info" rel="nofollow noreferrer">this helpful website</a>, the <a href="http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.aspx" rel="nofollow noreferrer">.Net Regular Expressions class</a>, and this very helpful book <a href="http://books.google.com/books?id=ucwR4KIvExMC" rel="nofollow noreferrer">Mastering Regular Expressions</a>.</p>\n'}, {'answer_id': 20341, 'author': 'Slavo', 'author_id': 1801, 'author_profile': 'https://Stackoverflow.com/users/1801', 'pm_score': 3, 'selected': False, 'text': '<p>The only situation in which I\'ve had to do this is sending a templated e-mail. In .NET this is provided out of the box by the <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.maildefinition.aspx" rel="noreferrer">MailDefinition class</a>. So this is how you create a templated message:</p>\n\n<pre><code>MailDefinition md = new MailDefinition();\nmd.BodyFileName = pathToTemplate;\nmd.From = "test@somedomain.com";\n\nListDictionary replacements = new ListDictionary();\nreplacements.Add("&lt;%To%&gt;", someValue);\n// continue adding replacements\n\nMailMessage msg = md.CreateMailMessage("test@someotherdomain.com", replacements, this);\n</code></pre>\n\n<p>After this, msg.Body would be created by substituting the values in the template. I guess you can take a look at MailDefinition.CreateMailMessage() with Reflector :). Sorry for being a little off-topic, but if this is your scenario I think it\'s the easiest way.</p>\n'}, {'answer_id': 20476, 'author': 'Gareth Farrington', 'author_id': 2021, 'author_profile': 'https://Stackoverflow.com/users/2021', 'pm_score': 2, 'selected': False, 'text': '<p>Regular expressions would be the quickest solution to code up but if you have many different tokens then it will get slower. If performance is not an issue then use this option.</p>\n\n<p>A better approach would be to define token, like your "##" that you can scan for in the text. Then select what to replace from a hash table with the text that follows the token as the key.</p>\n\n<p>If this is part of a build script then nAnt has a great feature for doing this called <a href="http://nant.sourceforge.net/release/latest/help/types/filterchain.html" rel="nofollow noreferrer">Filter Chains</a>. The code for that is open source so you could look at how its done for a fast implementation.</p>\n'}, {'answer_id': 21557, 'author': 'dguaraglia', 'author_id': 2384, 'author_profile': 'https://Stackoverflow.com/users/2384', 'pm_score': 2, 'selected': False, 'text': '<p>Well, depending on how many variables you have in your template, how many templates you have, etc. this might be a work for a full template processor. The only one I\'ve ever used for .NET is <a href="http://www.castleproject.org/others/nvelocity/index.html" rel="nofollow noreferrer">NVelocity</a>, but I\'m sure there must be scores of others out there, most of them linked to some web framework or another.</p>\n'}, {'answer_id': 7291301, 'author': 'ThisGuy', 'author_id': 910348, 'author_profile': 'https://Stackoverflow.com/users/910348', 'pm_score': 1, 'selected': False, 'text': '<p>If your template is large and you have lots of tokens, you probably don\'t want walk it and replace the token in the template one by one as that would result in an O(N * M) operation where N is the size of the template and M is the number of tokens to replace.</p>\n\n<p>The following method accepts a template and a dictionary of the keys value pairs you wish to replace.  By initializing the StringBuilder to slightly larger than the size of the template, it should result in an O(N) operation (i.e. it shouldn\'t have to grow itself log N times).</p>\n\n<p>Finally, you can move the building of the tokens into a Singleton as it only needs to be generated once.</p>\n\n<pre><code>static string SimpleTemplate(string template, Dictionary&lt;string, string&gt; replacements)\n{\n   // parse the message into an array of tokens\n   Regex regex = new Regex("(##[^#]+##)");\n   string[] tokens = regex.Split(template);\n\n   // the new message from the tokens\n   var sb = new StringBuilder((int)((double)template.Length * 1.1));\n   foreach (string token in tokens)\n      sb.Append(replacements.ContainsKey(token) ? replacements[token] : token);\n\n   return sb.ToString();\n}\n</code></pre>\n'}, {'answer_id': 11442008, 'author': 'Eric J.', 'author_id': 141172, 'author_profile': 'https://Stackoverflow.com/users/141172', 'pm_score': 2, 'selected': False, 'text': '<p><a href="http://www.codeproject.com/Articles/298519/Fast-Token-Replacement-in-Csharp" rel="nofollow">FastReplacer</a> implements token replacement in O(n*log(n) + m) time and uses 3x the memory of the original string.</p>\n\n<blockquote>\n  <p>FastReplacer is good for executing many Replace operations on a large string when performance is important.</p>\n  \n  <p>The main idea is to avoid modifying existing text or allocating new memory every time a string is replaced.</p>\n  \n  <p>We have designed FastReplacer to help us on a project where we had to generate a large text with a large number of append and replace operations. The first version of the application took 20 seconds to generate the text using StringBuilder. The second improved version that used the String class took 10 seconds. Then we implemented FastReplacer and the duration dropped to 0.1 seconds.</p>\n</blockquote>\n'}]
['https://Stackoverflow.com/questions/20267', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/1436/']