我正在尝试从字符串中解析“名称”和“地址”。我已经编写了 regex 模式,该模式非常好(我在 regex101.com 中验证过),具有 regex 的“ungreedy/lazy”功能,但没有贪婪。这是我的雪花查询:
select
TRIM(REGEXP_SUBSTR(column1,'(^\\D*)((\\bP[OST]*[ .]*O[FFICE]*[ .]*B[OX]*[ .]*\\d+.*)|(\\d+.*))[,.\\s]+([a-zA-Z]{2})[,.\\s]+(\\d{5}|\\d{5}-\\d{4})$',1,1,'is',1)) as test
from values(TRIM('FIRST SECOND THIRD PO BOX 123 DUMMY XX 12345-6789'));
--请忽略正则表达式的后半部分,因为我也在获取地区代码和邮政编码,并且它们工作正常。
上面的查询返回给我“FIRST SECOND THIRD PO BOX” 而且,如果我返回第二组,它会返回“123 DUMMY”
我想要的:
案例 1 - 当我的字符串是“FIRST SECOND THIRD PO BOX 123 DUMMY XX 12345-6789”
第一组输出:“FIRST SECOND THIRD”
第二组输出:“PO BOX 123 DUMMY”
案例 2 - 当我的字符串是 'FIRST SECOND THIRD FOURTH FIFTH 123 DUMMY XX 12345-6789'
第一组输出:“FIRST SECOND THIRD FOURTH FIFTH”
第二组输出:“123 DUMMY”
请在雪花中提出解决方法,因为它没有惰性功能。
附注。如果要在 regex101 中进行验证,请粘贴以下代码和测试字符串。当您切换到 Ungreedy 时,您将看到结果。 (^\D*)((\bP[OST][ .]O[FFICE][ .]B[OX][ .]\d+.)|(\d+.))[,.\s]+([a-zA-Z]{2})[,.\s]+(\d{5 }|\d{5}-\d{4})$
测试字符串:第一个第二个第三个邮政信箱 123 DUMMY XX 12345-6789
谢谢
答案 0 :(得分:2)
编写 JavaScrip UDF 始终是一种选择,然后您可以原封不动地使用正则表达式:
create or replace function parse_address(F STRING)
returns VARIANT
language JAVASCRIPT
immutable
as $$
const regex = /(^\D*)((\bP[OST]*[ .]*O[FFICE]*[ .]*B[OX]*[ .]*\d+.*)|(\d+.*))[,.\s]+([a-zA-Z]{2})[,.\s]+(\d{5}|\d{5}-\d{4})$/gm;
let m = regex.exec(F);
return [m[1], m[2]];
$$;
用法:
select parse_address($1)
from values('FIRST SECOND THIRD PO BOX 123 DUMMY XX 12345-6789')
, ('FIRST SECOND THIRD FOURTH FIFTH 123 DUMMY XX 12345-6789')
;