PySpark校验字符串列仅含指定字符时出现Py4JJavaError问题
PySpark正则校验字符串列报错Py4JJavaError的解决方法
问题描述
尝试用PySpark过滤Last12MonthsPaymentStatus列,仅保留包含0、S、U、-、1、?这些指定字符的行,使用代码如下:
from pyspark.sql.functions import col # 定义匹配允许字符的正则表达式 allowed_chars_regex = "^[0SU-1?]+$" # 使用rlike应用正则表达式过滤列 RPT_AR = RPT_AR.filter(col("Last12MonthsPaymentStatus").rlike(allowed_chars_regex))
原始数据表:
+------------------------------------+ |Last12MonthsPaymentStatus | +------------------------------------+ |000?000000000000000000?00?0000000000| |SSSSSSSSSSSSSSSSS0000000000000000S0S| |S???????00000000000SS?0000000000000?| |DDDDDDDDDDDDDD?DDDDDDDDBBB?BBBBBBBBS| |0?000???????????????????????????????| |DDD????DDDDDDD?DD0000DDBBB?BBBBBBBBS| |S10SSSSSSSSSSS??????????????????????| |S10SSSSSSSSSSSS?????????????????????| +------------------------------------+
期望输出结果:
+------------------------------------+ |Last12MonthsPaymentStatus | +------------------------------------+ |000?000000000000000000?00?0000000000| |SSSSSSSSSSSSSSSSS0000000000000000S0S| |S???????00000000000SS?0000000000000?| |0?000???????????????????????????????| |S10SSSSSSSSSSS??????????????????????| |S10SSSSSSSSSSSS?????????????????????| +------------------------------------+
但执行代码时抛出Py4JJavaError错误。
错误原因
正则表达式中的-在字符类[0SU-1?]中被当作范围运算符,SU-1会被解析为从U(ASCII码85)到1(ASCII码49)的字符范围,这是一个无效的反向范围,直接导致正则语法错误,触发Py4JJavaError。
解决方法
要让-被当作普通字符匹配,可采用以下两种方式:
- 将
-放在字符类的开头或结尾,避免被解析为范围运算符 - 用反斜杠
\转义-
修正后的正则表达式可选以下任意一种:
^[-01SU?]+$(-置于开头)^[01SU?-]+$(-置于结尾)^[0SU\-1?]+$(转义-)
修正后的代码示例:
from pyspark.sql.functions import col # 修正后的正则表达式(将-放在开头) allowed_chars_regex = "^[-01SU?]+$" # 过滤符合要求的行 RPT_AR = RPT_AR.filter(col("Last12MonthsPaymentStatus").rlike(allowed_chars_regex))
验证结果
执行修正后的代码后,会正确过滤掉包含D、B等非法字符的行,得到期望的输出结果。
内容的提问来源于stack exchange,提问作者RajatK350
相关产品推荐
相关产品推荐

