The replace string cannot contain special or break characters

Hi,
I’m currently getting the following error when trying to replace a tag within a document with a replacement string containing a special character (\r\n):
"The replace string cannot contain special or break characters."
Here is the code I’m using:

doc.Range.Replace(tag.Value, oSOADocumentTagList.GetItemValue(tag.Value), false, false);

The GetItem method returns the replacement tag value containing the CRLF.
NB: doc is of type Aspose.Words.Document
Is there a way I can replace text (tags) within the document with strings containing special characters like a CRLF?
Alain

Hi
Thanks for your request. I think here is the same question.

I think that you can use ReplaceEvaluator to solve this task. See the following link.
https://docs.aspose.com/words/net/find-and-replace/
Best regards.

What if I don’t want to use a regex?!? What if I want to simply use “old text”/“new text” as described in your API? The ReplaceEvaluator helper class is not really a good way to accomplish this, especially with large blocks of text.

HELP!!!

Hello,
Thank you for your inquiry.
You can use one of the overloads of the function Range.Replace. Here in our documentation has several examples of the use of different methods of replacement: https://docs.aspose.com/words/net/find-and-replace/. I hope this will be useful. If you have any questions, could you describe your problem more detailed, we will help find a solution.

Hi
Thanks for your inquiry. Actually, you can easily create a wrapper class and use IReplacingCallback internally. In this case you can expose only one method that accepts two parameters – old string and new string. For instance, I created a simple code:

[Test]
public void Test001()
{
    // Open input document.
    Document doc = new Document(@"Test001\in.doc");
    // Create helper and perform replace operation.
    ReplaceHelper helper = new ReplaceHelper(doc);
    helper.Replace("mytext", "This text can contain any special charactes\nparagraph break\fpage breaks, etc...");
    // Save output.
    doc.Save(@"Test001\out.doc");
}
// / 
// / helper class that allows replacing strign placeholders with text that contains special characters.
// / 
private class ReplaceHelper
{
    public ReplaceHelper(Document doc)
    {
        mDoc = doc;
    }
    // / 
    // / Replaces old text with new. New text can contain any special characters. Old text cannot contain special charactes.
    // / 
    // / 
    // / 
    public void Replace(string oldText, string newText)
    {
        mDoc.Range.Replace(new Regex(Regex.Escape(oldText)), new ReplaceEvaluatorFindAndInsertText(newText), false);
    }
    private class ReplaceEvaluatorFindAndInsertText : IReplacingCallback
    {
        public ReplaceEvaluatorFindAndInsertText(string text)
        {
            mText = text;
        }
        // / 
        // / This method is called by the Aspose.Words find and replace engine for each match.
        // / This method replaces 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))
            {
                runs.Add(currentNode);
                remainingLength = remainingLength - currentNode.GetText().Length;
                // Select the next Run node. 
                // Have to loop because there could be other nodes such as BookmarkStart etc.
                do
                {
                    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);
                runs.Add(currentNode);
            }
            // Create Document Buidler and insert text.
            DocumentBuilder builder = new DocumentBuilder(e.MatchNode.Document as Document);
            builder.MoveTo((Run)runs[runs.Count - 1]);
            builder.Write(mText);
            // Now remove all runs in the sequence.
            foreach (Run run in runs)
                run.Remove();
            // 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;
        }
        private string mText;
    }
    private Document mDoc;
}

Hope this helps.
Best regards,