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

PySpark正则提取ml前数字:从产品字段提取容量的问题

解决PySpark DataFrame中提取容量信息的正则表达式问题

原始DataFrame定义

from pyspark.sql.functions import *
from pyspark.sql.types import *

data = [
    ('1',"12345 soda bottle 1500ml"),
    ('2',"6789 beer can 450ml"),
    ("3","beer with no number before 375ml")
]
columnname = ['id','product']
df = spark.createDataFrame(data=data, schema=columnname)

原始数据展示

+---+--------------------------------+
|id |product                         |
+---+--------------------------------+
|1  |12345 soda bottle 1500ml        |
|2  |6789 beer can 450ml             |
|3  |beer with no number before 375ml|
+---+--------------------------------+

需求说明

新增volume和volume_number列,从product字段中提取容量信息:

  • volume:提取完整的容量格式(如1500ml)
  • volume_number:提取容量数值(如1500)
    需避开字段中无关数字的干扰。

尝试的代码及错误结果

尝试的代码:

df = df.withColumn('volume',regexp_extract(col('product'), '([0-9]{3,5}.*ml)', 1)
              ).withColumn('volume_number',regexp_extract(col('volume'), '^[^m]+', 0))

错误结果:

+---+--------------------------------+------------------------+----------------------+
|id |product                         |volume                  |volume_number         |
+---+--------------------------------+------------------------+----------------------+
|1  |12345 soda bottle 1500ml        |12345 soda bottle 1500ml|12345 soda bottle 1500|
|2  |6789 beer can 450ml             |6789 beer can 450ml     |6789 beer can 450     |
|3  |beer with no number before 375ml|375ml                   |375                   |
+---+--------------------------------+------------------------+----------------------+

期望输出

+---+--------------------------------+------------------------+----------------------+
|id |product                         |volume                  |volume_number         |
+---+--------------------------------+------------------------+----------------------+
|1  |12345 soda bottle 1500ml        |1500ml                  |1500                  |
|2  |6789 beer can 450ml             |450ml                   |450                   |
|3  |beer with no number before 375ml|375ml                   |375                   |
+---+--------------------------------+------------------------+----------------------+

正确解决方案

原正则表达式([0-9]{3,5}.*ml)的问题在于:它会匹配从第一个3-5位数字开始到ml的所有内容,导致包含了无关的前置文本和数字。

正确代码

df = df.withColumn('volume', regexp_extract(col('product'), r'(\d+ml)', 1)) \
       .withColumn('volume_number', regexp_extract(col('product'), r'(\d+)(?=ml)', 1))

正则说明

  • r'(\d+ml)':匹配**一个或多个数字紧跟ml**的内容,只提取带ml的容量单元,自动避开前面无ml后缀的无关数字。
  • r'(\d+)(?=ml)':使用正向预查(?=ml),匹配后面紧跟ml的数字,直接提取容量数值,无需依赖volume列,更高效。

运行上述代码后,将得到与期望完全一致的输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 23:31:00