You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PostgreSQL中对邮箱地址字符串进行掩码处理?

PostgreSQL 邮箱地址掩码实现方案

嘿,这个需求我之前做用户隐私数据处理的时候刚好碰到过!PostgreSQL虽然没有Excel那种直接指定起始位置和替换长度的REPLACE函数,但用它自带的字符串函数组合完全能搞定,而且还很灵活。

直接用SQL表达式实现

先上可以直接用的查询语句,以你的例子testemail@gmail.com为例,执行后就能得到te*****il@gmail.com:

SELECT 
  CONCAT(
    -- 取@前部分的前两位
    LEFT(local_part, 2),
    -- 生成对应数量的*:总长度减4(前2+后2),避免长度不足时出现负数
    REPEAT('*', GREATEST(LENGTH(local_part) - 4, 0)),
    -- 取@前部分的最后两位
    RIGHT(local_part, 2),
    '@',
    domain_part
  ) AS masked_email
FROM (
  -- 拆分邮箱为本地前缀和域名两部分
  SELECT 
    SPLIT_PART('testemail@gmail.com', '@', 1) AS local_part,
    SPLIT_PART('testemail@gmail.com', '@', 2) AS domain_part
) AS email_parts;

关键部分解释

  • SPLIT_PART(email, '@', 1):把邮箱按@拆分,取第一部分作为本地前缀(比如testemail),第二部分是域名(gmail.com),比用POSITION定位再截取更直观。
  • GREATEST(LENGTH(local_part) - 4, 0):这里是为了处理短前缀的情况——如果本地前缀长度小于4(比如ab@xxx.com),LENGTH(local_part)-4会是负数,用GREATEST强制取0,就不会生成多余的*,直接保留原前缀。
  • REPEAT('*', ...):根据计算出的数量重复生成*,完美替代中间需要隐藏的字符。

封装成自定义函数(复用更方便)

如果需要在多个地方使用这个逻辑,建议封装成一个自定义函数,还能顺便处理无效邮箱或NULL的情况:

CREATE OR REPLACE FUNCTION mask_email(email TEXT) 
RETURNS TEXT AS $$
BEGIN
  -- 处理NULL或不含@的无效邮箱,直接返回原内容
  IF email IS NULL OR POSITION('@' IN email) = 0 THEN
    RETURN email;
  END IF;
  
  RETURN CONCAT(
    LEFT(SPLIT_PART(email, '@', 1), 2),
    REPEAT('*', GREATEST(LENGTH(SPLIT_PART(email, '@', 1)) - 4, 0)),
    RIGHT(SPLIT_PART(email, '@', 1), 2),
    '@',
    SPLIT_PART(email, '@', 2)
  );
END;
$$ LANGUAGE plpgsql IMMUTABLE;

使用的时候就超简单:

-- 正常邮箱:返回te*****il@gmail.com
SELECT mask_email('testemail@gmail.com');

-- 短前缀邮箱:直接返回原内容(因为长度不足4,没有中间字符需要隐藏)
SELECT mask_email('ab@domain.com');

-- 长度为5的前缀:返回ab*yz@domain.com
SELECT mask_email('abcyz@domain.com');

内容的提问来源于stack exchange,提问作者shionblackcat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:10:52