java邮箱地址正则表达式_Java 中用正则表达式修改 Email 地址

需求

系统中有一列会用来存储 email 地址,现在需要对输入的字符串进行过滤,

要求是,把无效的地址过滤掉。有一些需要说明的是

这些地址是通过图像识别得到的,有些是用户自己输入的

已有历史记录已经存在了脏数据,需要替换

这个地址是识别出来的,不是用户帐号和联系信息这样的关键数据。所以宁愿相信用户是手误多录入的字符,或是机器识别把不该记录的字符当成 Email 的一部分了

测试字符串:

String[] arrEmailAddr = new String[]{

"\uD83D\uDC02abc123@cc.cc",

"A78=B[咔嚓]C⌚️2345@cc.cc",

"abc\uD83C\uDF32'sdfsd@sdfsd.·」cc",

"a·「d(*^@cc.cc",

"asl'''fgjk&^*'\"234@sgd_slgkj-sdfsd.com"

};

方案和坑

本以为用了很多年正则,已经很熟练了,应该信手拈来,没想到实际操作时居然遇到那么多坑

首先可以确定的是,使用 Java 的 ReplaceAll 是没错了

网上广为流传的神 Pattern

// 清除掉所有特殊字符

String regEx="[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]";

Pattern p = Pattern.compile(regEx);

Matcher m = p.matcher(str);

return m.replaceAll("").trim();

首先,我是十分讨厌这种穷举法的;其次,对层出不穷的特殊字符控制不足,比如全角空格、颜文字等等。

pass

按照 Email 的格式严格匹配,把不符合 Email 格式的直接替换掉

是个比较彻底的方法,但是,实际操作前,发现有这样一些让人无语的脏数据:

+--------+----------------------------------------------------+

| id | email |

+--------+----------------------------------------------------+

| 66898 | 信箱三-mail:zhixxxxxxxxxx@163.com |

| 115764 | 邮箱:1xxxxxx890@qq.com |

| 513557 | M0:svxxxxxx@vip.163.c0m |

| 708165 | 邮箱:lixxxxxxxx@zjlcwg.com |

| 966373 | Mail:chenxxxxxx@ch-jht.com |

+--------+----------------------------------------------------+

5 rows in set (0.05 sec)

这些记录不在少数,肯定需要保留。

所以,问题还是回到 替换 这条思路上来

使用白名单

实际上只能这么做,难点和坑也在于这里,先列几个我犯的错误示例:

String regEx = "/[0-9a-z]/"; // 这是一个正向测试,不过测试本身就有问题,Java里面不是用 “/” 来标识两端的

String regEx="[^0-9][^a-z][^_]"; // 这样会顺序匹配,在每个匹配组上干掉了其他组的合法字符

String regEx="(\\W|@|-....)"; // 匹配到第一个之后,就直接过滤掉了,后面的其他字符不会被保留

String regEx="^[a-z0-9-_@]"; // ^ 字符匹配的是字符串开始的地方,无法作为 “非” 来使用,加转译就更不对了

String regEx="[^0-9a-z.-_@]"; // 这个就坑大了,自己看结果:

/** -----

abc123@cc.cc

A78=B[]C2345@cc.cc

abcsdfsd@sdfsd.cc

ad^@cc.cc

aslfgjk^234@sgd_slgkjsdfsd.com

---- */

// 问题在于,“.” 这个字符,在里面会被认为是任意字符的匹配,对反斜线“免疫”

最终结果

测试字符

见文首

正则源码

正如上文说的,“.” 字符必须放末位

// 与下面的等价 String regEx="[^0-9a-z-_@.]";

String regEx="[^\\w-@.]";

输出

abc123@cc.cc

782345@cc.cc

abcsdfsd@sdfsd.cc

ad@cc.cc

aslfgjk234@sgd_slgkj-sdfsd.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值