We're sorry Aspose doesn't work properply without JavaScript enabled.

Free Support Forum - aspose.com

Find and Replace tags with curly {{brackets}}

We have existing template in Word that uses {{ as open tag and }} as closing tag. I’ve tried 2 hrs but am not able to do the REPLACE unless I use underscore to open and close tag.

Is there an escape character that I can use? Some examples will be very much appreciated. Thanks.


Thanks for your request. You can use simple replace method to replace such tags with values. See the code below:

Document doc = new Document(@"Test001\in.doc");

doc.Range.Replace("{{tag}}", "value", false, false);


Also, you can replace all such tags with merge fields and use Mail Merge feature to fill the document with data. Please see the following link and code below:


NOTE: when you use curly brackets in regular expression, you should escape it with backslash because curly brackets are reserved.


public void Test001()


Document doc = new Document(@"Test001\in.doc");

doc.Range.Replace(new Regex(@"\{\{(?.*?)\}\}"), new ReplaceEvaluatorFindAndInsertMergefield(), false);



private class ReplaceEvaluatorFindAndInsertMergefield : IReplacingCallback



/// This method is called by the Aspose.Words find and replace engine for each match.

/// This method highlights the match string, even if it spans multiple runs.


ReplaceAction IReplacingCallback.Replacing(ReplacingArgs e)


// This is a Run node that contains either the beginning or the complete match.

Node currentNode = e.MatchNode;

// The first (and may be the only) run can contain text before the match,

// in this case it is necessary to split the run.

if (e.MatchOffset > 0)

currentNode = SplitRun((Run)currentNode, e.MatchOffset);

// This array is used to store all nodes of the match for further removing.

ArrayList runs = new ArrayList();

// Find all runs that contain parts of the match string.

int remainingLength = e.Match.Value.Length;

while (

(remainingLength > 0) &&

(currentNode != null) &&

(currentNode.GetText().Length <= remainingLength))



remainingLength = remainingLength - currentNode.GetText().Length;

// Select the next Run node.

// Have to loop because there could be other nodes such as BookmarkStart etc.



currentNode = currentNode.NextSibling;


while ((currentNode != null) && (currentNode.NodeType != NodeType.Run));


// Split the last run that contains the match if there is any text left.

if ((currentNode != null) && (remainingLength > 0))


SplitRun((Run)currentNode, remainingLength);



// Create Document Buidler aond insert MergeField

DocumentBuilder builder = new DocumentBuilder(e.MatchNode.Document as Document);

builder.MoveTo((Run)runs[runs.Count - 1]);

string fieldName = e.Match.Groups["FieldName"].Value;

builder.InsertField(string.Format("MERGEFIELD {0}", fieldName), string.Format("«{0}»", fieldName));

// Now remove all runs in the sequence.

foreach (Run run in runs)


// Signal to the replace engine to do nothing because we have already done all what we wanted.

return ReplaceAction.Skip;



/// Splits text of the specified run into two runs.

/// Inserts the new run just after the specified run.


private static Run SplitRun(Run run, int position)


Run afterRun = (Run)run.Clone(true);

afterRun.Text = run.Text.Substring(position);

run.Text = run.Text.Substring(0, position);

run.ParentNode.InsertAfter(afterRun, run);

return afterRun;



Hope this helps.

Best regards.

Thank you, Alexey, for the quick response. This was exactly what I did:

int iReplaceCount;
//Open the template document
string templateFile = Request.PhysicalApplicationPath + “Test.docx”;
string docContract = Request.PhysicalApplicationPath + “Test.pdf”;
Document doc = new Document(templateFile);

// Replace TAG with content
string text = doc.Range.Text;
iReplaceCount = doc.Range.Replace("{{CLIENT_NAME}}", “D Huynh”, false, true);
iReplaceCount = doc.Range.Replace("{{DAY_SHORT}}", DateTime.Today.ToShortDateString(), false, true);
// Display in browser
doc.Save(Response, “Test.pdf”, ContentDisposition.Inline, null);

This is what’s in side test.docx:




and this is what in the PDF:


The same code works perfectly if I replace the {{ and }} with __ and __. Do I miss a patch? I just downloaded the DLL a week ago. I've attached both files, please review. Thanks.


Thanks for your request. The problem occurs because you set isMatchWholeWord parameter to true. Curly brackets cannot be a part of word, that is why your code does not work. Please try setting it to false as I did in my code:

doc.Range.Replace("{{tag}}", "value", false, false);

Best regards,

I am sure it is somewhere in the documentation that I overlooked. Thank you!!! You saved me tons of headache, and I am placing my order :wink: