How to replace the given email address with a value in a given input? I have written the below method to replace some of the email domains like @gmail.com and @yahoo.com with a given text.
public static string RemovePersonalInfo(string input)
{
    string[] tokens = input.Split(new char[] { ' ', '\t', '\r', '\n' });
    string output = string.Empty;
    foreach (string token in tokens)
    {
        if (token.Contains(&quot;@gmail.com&quot;))
        {
            output += &quot; SOMETEXT&quot;;
        }
        else
        {
            output += &quot; &quot; + token;
        }
    }
    tokens = output.Split(new char[] { ' ', '\t', '\r', '\n' });
    output = string.Empty;
    foreach (string token in tokens)
    {
        if (token.Contains(&quot;@yahoo.com&quot;))
        {
            output += &quot; SOMETEXT&quot;;
        }
        else
        {
            output += &quot; &quot; + token;
        }
    }
    return output;
}

It is working as expected for the below input.
But I don't think it is a good solution, I can see the improvements in the code like it is not scalable, let's see tomorrow some other email domain comes, I will have to again modify the code and write another if condition. the second improvement is that I am running the loop twice, it can be done in one loop. so performance can be improved.
Or if there is any better approach than this, please suggest.
Input: test@gmail.com test@abc.com @teest@yahoo.com
Output:   SOMETEXT test@abc.com SOMETEXT
Note: I am not supposed to use the Replace method. So the only intention here is to use the same logic in basic programming languages like C and C++ as well.
Performance wise using string concatination (output += ) inside a loop isn't the best choice because for each output +=  a new string is created because strings are immutable. Using a StringBuilder would be the way to go. But instead of returning a string, you could return an IEnumerable&lt;string&gt; which would make the code more flexible.

Passing an IEnumerable&lt;string&gt; as method parameter holding the not wanted domains will make the code open for needed changes.

Passing an IEnumerable&lt;string&gt; as method parameter holding the tokens would enable the method to only do one thing.

Because the method is public you should have proper parameter validation.

Using a little bit of Linq would compact the code a lot.

Instead of hardcoding &quot;SOMETEXT&quot; you could pass an optional parameter.


Implementing the mentioned changes using string as return-type would lead to
public static string RemovePersonalInfo(string input)
{
    if (input == null) { throw new NullReferenceException(nameof(input)); }
    if (string.IsNullOrWhiteSpace(input)) { return input; }

    return RemovePersonalInfo(input.Split(new char[] { ' ', '\t', '\r', '\n' }), new string[] { &quot;@gmail.com&quot;, &quot;@yahoo.com&quot; });

}
private static string RemovePersonalInfo(IEnumerable&lt;string&gt; tokens, IEnumerable&lt;string&gt; domains, string replacement = &quot;SOMETEXT&quot;)
{
    return string.Join(&quot; &quot;, tokens.Select(token =&gt; (domains.Any(domain =&gt; token.Contains(domain)) ? replacement : token)));
}  

and could be called like before.