• 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
    
    
  • 相关阅读:
    2021年Mysql个税计算公式,自定义函数
    安装篇-安装mysql8
    安装篇-安装Nginx
    jsconfig.json配置Webpack别名,识别@
    Avue动态校验表单的必填校验
    renren开源把时间类型Date换为LocalDate报错
    Avue的CRUD最强封装(三)
    Avue-curd通用模板(二)
    Kalman Filter算法详解
    STM32 ADC DMA 中断模式多通道读取ADC转换值
  • 原文地址:https://www.cnblogs.com/mslagee/p/10185759.html
Copyright © 2020-2023  润新知