简体   繁体   中英

C# Regex for masking E-Mails

Is there a simple way for masking E-Mail addresses using Regular Expressions in C# ?

My E-Mail :

myawesomeuser@there.com

My goal :

**awesome****@there.com (when 'awesome' was part of the pattern)

So it's more like an inverted replacement where evertyhing that does not actually match will be replaced with * .

Note : The domain should never be replaced!

From a performance side of view, would it make more sense to split by the @ and only check the first part then put it back together afterwards?

Note : I don't want to check if the E-Mail is valid or not. It's just a simple inverted replacement and only for my current needs, the string is an E-Mail but for sure it can be any other string as well.

Solution

After reading the comments I ended up with an extension-method for strings which perfectly matches my needs.

public static string MaskEmail(this string eMail, string pattern)
{
    var ix1 = eMail.IndexOf(pattern, StringComparison.Ordinal);
    var ix2 = eMail.IndexOf('@');

    // Corner case no-@
    if (ix2 == -1)
    {
        ix2 = eMail.Length;
    }

    string result;

    if (ix1 != -1 && ix1 < ix2)
    {
        result = new string('*', ix1) + pattern + new string('*', ix2 - ix1 - pattern.Length) + eMail.Substring(ix2);
    }
    else
    {
        // corner case no str found, all the pre-@ is replaced
        result = new string('*', ix2) + eMail.Substring(ix2);
    }

    return result;
}

which then can be called

string eMail = myawesomeuser@there.com;

string maskedMail = eMail.MaskEmail("awesome"); // **awesome****@there.com
string email = "myawesomeuser@there.com";
string str = "awesome";

string rx = "^((?!" + Regex.Escape(str) + "|@).)*|(?<!@.*)(?<=" + Regex.Escape(str) + ")((?!@).)*";

string email2 = Regex.Replace(email, rx, x => {
    return new string('*', x.Length);
});

There are two sub-regular expressions here:

^((?!" + Regex.Escape(str) + "|@).)*

and

(?<!@.*)(?<=" + Regex.Escape(str) + ")((?!@).)*

They are in | (or)

The first one means: from the start of the string, any character but stop when you find str (escaped) or @

The second one means: there mustn't be a @ before the start of this matching and, starting from str (escaped), replace any character stopping at the @

Probably faster/easier to read:

string email = "myawesomeuser@there.com";
string str = "awesome";

int ix1 = email.IndexOf(str);
int ix2 = email.IndexOf('@');

// Corner case no-@
if (ix2 == -1) {
    ix2 = email.Length;
}

string email3;

if (ix1 != -1 && ix1 < ix2) {
    email3 = new string('*', ix1) + str + new string('*', ix2 - ix1 - str.Length) + email.Substring(ix2);
} else {
    // corner case no str found, all the pre-@ is replaced
    email3 = new string('*', ix2) + email.Substring(ix2);
} 

This second version is better because it handle corner cases like: string not found and no domain in the email.

(awesome)|.(?=.*@)

Try this.Replace by *$1 .But there will be an extra * at the start.So remove a * from the masked email from the start.See demo.

https://regex101.com/r/wU7sQ0/29

Non RE;

string name = "awesome";
int pat     = email.IndexOf('@');
int pname   = email.IndexOf(name);

if (pname < pat)
    email = new String('*', pat - name.Length).Insert(pname, name) + email.Substring(pat);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM