• Java 中用正则表达式修改 Email 地址


    需求

    系统中有一列会用来存储 email 地址,现在需要对输入的字符串进行过滤,
    要求是,把无效的地址过滤掉。有一些需要说明的是

    1. 这些地址是通过图像识别得到的,有些是用户自己输入的
    2. 已有历史记录已经存在了脏数据,需要替换
    3. 这个地址是识别出来的,不是用户帐号和联系信息这样的关键数据。所以宁愿相信用户是手误多录入的字符,或是机器识别把不该记录的字符当成 Email 的一部分了

    测试字符串:

    String[] arrEmailAddr = new String[]{
        "uD83DuDC02abc123@cc.cc",
        "A78=B[咔嚓]C⌚️2345@cc.cc",
        "abcuD83CuDF32'sdfsd@sdfsd.·」cc",
        "a·「d(*^@cc.cc",
        "asl'''fgjk&^*'"234@sgd_slgkj-sdfsd.com"
    };
    

    方案和坑

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

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

    1. 网上广为流传的神 Pattern

      // 清除掉所有特殊字符 
      String regEx="[`~!@#$%^&*()+=|{}':;',\[\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]";   
      
      Pattern p = Pattern.compile(regEx); 
      
      Matcher m = p.matcher(str);  
      
      return m.replaceAll("").trim();
      

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

      pass

    2. 按照 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)
      
      

      这些记录不在少数,肯定需要保留。
      所以,问题还是回到 替换 这条思路上来

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

      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
    
    
  • 相关阅读:
    PhotoshopCS6中文版图像处理实战从入门到精通
    Web安全开发指南
    OpenStack运维指南
    Word/Excel/PPT 2016高效办公实战从入门到精通
    UG NX 8.5中文版基础教程
    Moldflow 2018模流分析从入门到精通:升级版
    数据库与数据处理:Access 2010实现
    iOS开发网络数据之AFNetworking使用1
    AFNetworking2.5使用2
    iOS项目的完整重命名方法图文教程
  • 原文地址:https://www.cnblogs.com/mslagee/p/10185759.html
Copyright © 2020-2023  润新知