Presto regexp_replace正则报错,同规则在regex101 Java8模式正常如何解决?
解决Presto中look-behind正则表达式报错问题
问题背景
原正则表达式(?<!timeFrame:"(?:\d\d?\d?\d?)?)[0-9.\/,]在regex101的Java8模式下可正常运行,能够删除timeFrame:"..."以外位置的数字、点、斜杠和逗号,但在Presto SQL的regexp_replace函数中执行时,出现错误:
java.sql.SQLException: [Simba]AthenaJDBC An error has been thrown from the AWS Athena client. INVALID_FUNCTION_ARGUMENT: invalid pattern in look-behind
测试字符串:timeFrame:"122 Days" ipAddress:1.1.1.1
预期结果:timeFrame:"122 Days" ipAddress:
错误原因
原正则的look-behind断言中包含了可变长度的子表达式\d\d?\d?\d?(匹配1-4位数字),虽然Java 8理论上支持有限长度的look-behind,但Presto(或AWS Athena)的正则引擎实现对look-behind的长度限制更为严格,不允许包含不确定长度的匹配逻辑,因此触发报错。
解决方案:改用捕获组实现需求
绕开look-behind的限制,通过捕获组保留需要的内容,替换掉目标字符。修改后的正则表达式和执行语句如下:
SELECT regexp_replace( 'timeFrame:"122 Days" ipAddress:1.1.1.1', '(timeFrame:"[^"]+")|([0-9.\/,])', '$1' ) AS result;
逻辑解释
- 正则分为两个匹配分支:
(timeFrame:"[^"]+"):捕获完整的timeFrame:"..."内容,保留这部分不做修改([0-9.\/,]):匹配需要删除的数字、点、斜杠和逗号
- 替换时使用
$1,即仅保留第一个捕获组的内容,匹配到第二个分支的字符则替换为空,最终实现保留timeFrame内的目标字符、删除其他位置目标字符的效果。
验证结果
执行上述语句后,得到预期结果:timeFrame:"122 Days" ipAddress:
内容的提问来源于stack exchange,提问作者O-O-O
相关产品推荐
相关产品推荐

