使用正则表达式掩盖域名电子邮件地址

6

我的客户希望在邮件中掩盖电子邮件,按照以下方式进行:

原始电子邮件:

1 userone@domain.com

2 usertwo@domain.com.co --- > 可以是任何东西,如gov.co,.com.mx等

掩盖的电子邮件:

1 u*****e@d****n.com

2 u*****o@d****n.com.co

对于第一个案例,我有这个:

string pattern = @"(?<=[\w]{1})[\w-\._\+%]*(?=[\w]{1}@)"; // ---> mask before "@"
string p2 = @"(?<=[\w]{1})[\w-\+%]*(?=[\w]{1}[.])"; // --- > mask after "@"
string result = Regex.Replace(mail, pattern, m => new string('*', m.Length));
string newresult = Regex.Replace(result, p2, m => new string('*', m.Length));
Console.WriteLine("Masked email: {0}", newresult);

并且正常工作:

MaskedEmail first case

但是...第二种情况无法正常工作...

那么,适用于 "@" 后面的两种情况的正则表达式是什么?


通过“第二种情况不起作用”,我认为您的意思是因为它将“.com.”更改为“.c*m.”? - ctwheels
是的,没错。 - makitocode
1
不一定总是有效,因为它有许多缺陷。但你可能会从中得到一些想法。\B.\B(?=\w*(?:@|\.com)) - Gurmanjot Singh
2
@Gurman 你上面的解决方案确实可行,但取决于是否存在“.com”。我已经在我的解决方案中加入了你的想法,但使用了可变长度回顾(在 .net 中受支持)。我已经为原始想法给予了你信用。 - ctwheels
1个回答

10

原始答案

请参见我的答案底部的编辑,了解在 .net 中可以通过第二种方法实现此操作(更短)。

代码

在此查看使用的正则表达式

(?:(?:^|(?<=@))([^.@])|\G(?!\A))[^.@](?:([^.@])(?=[.@]))?

替换: $1*$2

用法

在此处查看使用的代码

using System;
using System.Text.RegularExpressions;
 
public class Example
{
    public static void Main()
    {
        string pattern = @"(?:(?:^|(?<=@))([^.@])|\G(?!\A))[^.@](?:([^.@])(?=[.@]))?";
        string substitution = @"$1*$2";
        string input = @"userone@domain.com
usertwo@domain.com.co";
        RegexOptions options = RegexOptions.Multiline;
 
        Regex regex = new Regex(pattern, options);
        Console.WriteLine(regex.Replace(input, substitution));
    }
}

结果

输入

userone@domain.com
usertwo@domain.com.co

输出

u*****e@d****n.com
u*****o@d****n.com.co

解释

  • (?:(?:^|(?<=@))([^.@])|\G(?!\A)) 匹配以下任一内容
    • (?:^|(?<=@))([^.@]) 匹配以下内容
      • (?:^|(?<=@)) 匹配以下任一内容
        • ^ 断言当前位置在行首
        • (?<=@) 正向先行断言,确保前面是字符@
      • ([^.@]) 捕获除了点号.或者符号@以外的任意字符到第一个捕获组
    • \G(?!\A) 断言当前位置在上一个匹配的结尾
  • [^.@] 匹配除了点号.或者符号@以外的任意字符
  • (?:([^.@])(?=[.@]))? 匹配以下内容零次或一次
    • ([^.@]) 捕获除了点号.或者符号@以外的任意字符到第二个捕获组
    • (?=[.@]) 正向先行断言,确保后面是点号.或者符号@


编辑

这个模式得到的结果与我的原始答案相同(除非给出长度为2的字符串:即un@domain.com保持不变,而原始答案将使其成为u*@domain.com)。

C# (.net)支持可变长度回溯。感谢@Gurman的评论。他走在了正确的轨道上,只是可能不知道.net支持可变长度回溯。

代码

在此处查看使用的正则表达式

(?<=(?:^|@)[^.]*)\B.\B

解释

  • (?<=(?:^|@)[^.]*) 正向后查找,确保后面的内容匹配
    • (?:^|@) 匹配行首或者字母符号 @
    • [^.]* 匹配除了句号 . 以外的任何字符
  • \B 匹配一个单词边界不匹配的位置
  • . 匹配任何字符
  • \B 匹配一个单词边界不匹配的位置

编辑2

包含.的电子邮件本地部分的正则表达式(在此处使用):

(?<=^[^@]+)[^@](?=[^@])|(?<=@[^.]+)[^.](?=[^.])

@Makitodev,你可以使用regex101自动生成的脚本进行测试。我也用regexstorm.net测试过了,它是有效的 - ctwheels
@Makitodev,我更新了我的答案,包括代码和一个链接,在C#中运行它(在ideone上)。 - ctwheels
1
@Makitodev 我添加了一个比原来短得多的编辑。它只能在支持可变长度回顾后发动机的正则表达式引擎中工作,但 .net 就是其中之一。 - ctwheels
1
@Makitodev 我很高兴能帮助您解决问题!是的,现在确实存在回答问题但没有解释的问题(尤其是标记为[tag: regex]的问题)。如果您对上述内容有任何疑问,请随时提出 :) - ctwheels
1
不太好处理用户名部分的点,以及域名部分的连字符。例如,user.two@some-mail.co.uk 变成了 u**r.two@s**e-m**l.co.uk - dizarter
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接