Find and Replace with rearranging

Hello,

This is probably a very simple operation but I can’t seem to get it to work.

I am changing many files to new formatting, and as such will be trying find and replace methods as well as rearranging text. One that I can’t quite figure out is like this:

LastName, FirstName

Which the format should now be :

FirstName LastName - JobTitle

While I can easily add the Job Title, I am having issue with parsing the Name part - rearranging them and removing the comma, as I don’t know how long the name is and for some of them, there is no comma to divide by (only a space). I can’t seem to use Find and Replace as I don’t know the name itself (I want to get it from the document) and just change the arrangement of the text.

There are a few other things to do (replacing parts of the document, rearranging text) but if I can get this to work, I can surely get the rest.

Is there some example code for taking text and rearranging? I feel like it should be obvious but I can’t figure it out.

Thanks for your assistance.

@cstaub for your case you can use the IReplacingCallback interface with the Replace method. I create a simple example for you:

Document doc = new Document("C:\\Temp\\input.docx");
Document clonDoc = (Document)doc.Clone(true);

FindReplaceOptions opt = new FindReplaceOptions()
{
    ReplacingCallback = new ReplaceCallBack(new List<string> { "Engineer", "Doctor", "Architect" })
};


var text = clonDoc.FirstSection.Body.Range.Replace("Doe, Jhon", "-", opt);
clonDoc.Save("C:\\Temp\\output.docx");

public class ReplaceCallBack : IReplacingCallback
{
    private readonly List<string> _jobTitles;
    private int _counter = 0;
    public ReplaceCallBack(List<string> jobTitles) {
        _jobTitles = new List<string>();
        _jobTitles.AddRange(jobTitles);
    }

    public ReplaceAction Replacing(ReplacingArgs args)
    {
        if(_counter >= _jobTitles.Count)
        {
            _counter = 0;
        }

        var replaceText = $"{args.Replacement} {_jobTitles[_counter]}";
        var value = args.Match.Value.ToString();
        var commaIndex = value.IndexOf(",");
        args.Replacement = $"{value.Substring(commaIndex + 1).Trim()} {value.Substring(0, commaIndex)} {replaceText}";

        _counter++;

        return ReplaceAction.Replace;
    }
}

The Replace method also accept the use of regular expressions as a parameter, so you can use it to find the target text to replace. Unfortunately for your case the pattern to identify the combination of name and lastname is not clear so maybe you need to use a Dictionary.
input.docx (15.0 KB)

This is good, but I am trying not to pass in the name values (there is more than 250 of them), and it is just a list, not a paragraph.

I’m hoping for something, even if it can only find the comma ones, to take

Doe, John

And do something like

If format is “AnyText, MoreText” to change to “MoreText AnyText”

without passing in the names themselves, like to use a wildcard or something that just looks for that format of "SomeWord, AnotherWord) and flips them ?
To explain another way, to find any two words separated by ", " and switch their positions as in this file, only the names are comma separated

So :
x, y
abc, def
this, that

changes to :
y x
def abd
that this

Without knowing the values being exchanged? After this, I can just append each line with the title which I have already succeeded with. If this works (finding the comma) then I can just take all the spaces and replace with ", " to make all other lines valid for this.

I hope this makes sense, thanks for your swift reply.

@cstaub as I said Replace method support the use of regular expressions, so for the case of comma separated name and lastname format you can use the following expression:

var regex = new Regex(@"[A-Z]{1}[a-z]{2,15},\s[A-Z]{1}[a-z]{2,15}");
clonDoc.FirstSection.Body.Range.Replace(regex, "-", opt);

You’re correct, I missed that on the first read. That is perfect, I was just being silly today. Thanks for your help!

1 Like