Spark SQL正则提取问题:Athena正则迁移后失效
问题分析与解决方案
你的问题主要出在两个核心点上:Spark SQL的REGEXP_EXTRACT函数行为差异,以及正则表达式捕获组的使用,咱们一步步拆解清楚:
1. Spark SQL REGEXP_EXTRACT的默认行为差异
Athena(基于Presto)的REGEXP_EXTRACT如果不指定捕获组,默认返回整个匹配的字符串;但Spark SQL的REGEXP_EXTRACT默认返回第一个捕获组(括号包裹的内容),这是导致结果不符合预期的关键原因。
你写的正则'X10003([^\s]+)'里,([^\s]+)是一个独立的捕获组,所以Spark默认只提取这部分内容(也就是X10003后面的所有非空格字符),而不是包含X10003的完整目标串。
2. 正则匹配范围的小细节
另外你提到结果包含了(CAMP),这说明你的目标字符串中20443和(之间可能没有空格?如果你的需求是提取从X10003开始到第一个空格前的内容,[^\s]+会匹配所有非空白字符(包括括号、字母等),直到遇到第一个空格为止;如果X10003...后面没有空格,它会一直匹配到字符串末尾。
正确的Spark SQL写法
针对你的需求,有两种简单的修正方式:
方式一:去掉捕获组,匹配整个目标串
直接写正则匹配X10003开头的所有非空格字符,Spark会返回整个匹配结果:
REGEXP_EXTRACT("5570 - Site 811111 - X10003-10447-XXX-20443 (CAMP)", 'X10003[^\s]+')
运行后会返回X10003-10447-XXX-20443,完全符合你的需求。
方式二:指定捕获组0(整个匹配)
如果你需要保留捕获组(比如后续有其他复杂匹配需求),可以明确指定第三个参数为0,表示返回整个匹配的内容:
REGEXP_EXTRACT("5570 - Site 811111 - X10003-10447-XXX-20443 (CAMP)", '(X10003[^\s]+)', 0)
同样能得到正确的结果。
内容的提问来源于stack exchange,提问作者shzyincu
相关产品推荐
相关产品推荐

