PySpark删除列表列最后一个元素 提取邮箱域名及后缀方法
PySpark 邮箱域名提取方案
不用纠结拆分后变长列表的元素删除逻辑,直接基于原始email字段用正则提取是容错率最高的方案,完全覆盖两个约束:不管域名本身带多少个点、不管后缀长度多少都能准确匹配。
方法1:正则直接提取(最推荐,零依赖中间列)
核心匹配逻辑:
- 以
@作为域名段的起始锚点 - 最后一个
.之后的内容为域名后缀,和你之前拆分列表取最后一个元素的结果完全一致 @之后到最后一个.之前的所有内容即为需要提取的域名主体,天然适配域名中包含多个.的场景
PySpark实现代码:
from pyspark.sql import functions as F # 示例数据构造 df = spark.createDataFrame([ ("user1@gmail.com",), ("user2@hotmail.co.uk",), ("user3@mail.example.org",), ("user4@sub.domain.test.net",) ], ["email"]) # 字段提取 result_df = df.withColumn( "domain_suffix", F.regexp_extract("email", r"\.([^.]+)$", 1) ).withColumn( "domain_name", F.regexp_extract("email", r"@(.+)\.[^.]+$", 1) ) result_df.show(truncate=False)
运行输出结果:
+-------------------------+-------------+---------------+ |email |domain_suffix|domain_name | +-------------------------+-------------+---------------+ |user1@gmail.com |com |gmail | |user2@hotmail.co.uk |uk |hotmail.co | |user3@mail.example.org |org |mail.example | |user4@sub.domain.test.net|net |sub.domain.test| +-------------------------+-------------+---------------+
如果你的业务规则里域名后缀包含多级(例如将
.co.uk作为完整后缀),只需要调整正则的后缀匹配规则即可,核心逻辑无需改动。
方法2:复用已有的test拆分列实现
如果你需要复用已经生成的test列(按.拆分邮箱得到的变长数组列),不需要手动遍历删除列表最后一个元素,直接用内置函数slice截取数组后拼接即可,完全适配变长列表的场景:
# 假设当前df已经存在按.拆分email得到的test数组列 result_df2 = df.withColumn( # 截取数组从第1位开始、长度为数组总长度-1的元素,即去掉最后一个元素 "domain_part_list", F.slice("test", 1, F.size("test") - 1) ).withColumn( # 把截取后的数组用.拼接回字符串,再按@拆分取最后一段,即为域名主体 "domain_name", F.element_at(F.split(F.concat_ws(".", "domain_part_list"), "@"), -1) ).withColumn( # 取数组最后一个元素作为后缀,和你之前的逻辑一致 "domain_suffix", F.element_at("test", -1) )
方案选型参考
- 正则提取方案不需要生成中间拆分列,计算链路短、性能更好,不受拆分逻辑的边缘case影响,优先选用
- 复用test列的方案适合已经做了大量前置计算、不想重新处理原始列的场景,同样可以解决变长列表无法固定索引截取的问题
内容的提问来源于stack exchange,提问作者SuperBanana
相关产品推荐
相关产品推荐

