Sql 实现regex_替换的更智能的方法?

Sql 实现regex_替换的更智能的方法?,sql,regex,snowflake-cloud-data-platform,Sql,Regex,Snowflake Cloud Data Platform,我正在尝试使用regex_替换来解决这个问题,但不知道是否有更聪明的方法来解决它,并阻止我在将来添加更多嵌套的regex_替换函数来解释每个场景 有关设置,请参阅以下SQLFIDLE 我试图解决的主要问题是重复值“ACK”或“ZEBRA”或它们的组合 所以基本上它不应该同时有斑马和羚羊。如果是的话,那就带上离号码最近的ACK或斑马 确认确认DOV应为确认DOV 斑马应该是斑马 斑马驼背应该是驼背 斑马斑马应该是斑马 斑马线应该是斑马线 斑马应该是斑马 价值 固定的 理想的 确认确认确认确认900

我正在尝试使用regex_替换来解决这个问题,但不知道是否有更聪明的方法来解决它,并阻止我在将来添加更多嵌套的regex_替换函数来解释每个场景

有关设置,请参阅以下SQLFIDLE

我试图解决的主要问题是重复值“ACK”或“ZEBRA”或它们的组合

所以基本上它不应该同时有斑马和羚羊。如果是的话,那就带上离号码最近的ACK或斑马

  • 确认确认DOV应为确认DOV
  • 斑马应该是斑马
  • 斑马驼背应该是驼背
  • 斑马斑马应该是斑马
  • 斑马线应该是斑马线
  • 斑马应该是斑马
  • 价值 固定的 理想的 确认确认确认确认90000 阿克多夫90000 阿克多夫90000 ACK_910101 ACK_910101 ACK_910101 阿克希斯90000000 阿克希斯90000000 阿克希斯90000000 GGG_u0000000 GGG_u0000000 GGG_u0000000 ASC_VNA_303930 ASC_VNA_303930 ASC_VNA_303930 ACK_393848489 ACK_393848489 ACK_393848489 ACK_VNA_30303 ACK_VNA_30303 ACK_VNA_30303 ACK_XPM_303030 ACK_XPM_303030 ACK_XPM_303030 确认确认确认多夫39393 ACK_DOV_39393 ACK_DOV_39393 斑马03930 斑马03930 斑马03930 斑马 斑马 斑马 斑马鱼3930321 斑马鱼3930321 斑马鱼3930321 斑马驼背驼背驼背3934994 斑马队3934994 阿克多夫3934994 斑马斑马293930 斑马斑马293930 斑马29393930
    不要使用正则表达式,因为没有可用的反向匹配语法,而是将逻辑转换为按下划线拆分,计算出现的标记“坏”的次数,只保留好的或最后一个坏的,然后将它们粘在一起

    with data(value,fixed,ideal) as (
        select * from values
            ('ACK_ACK_DOV_90000','ACK_VOD_90000','ACK_VOD_90000')
            ,('ACK_910101','ACK_910101','ACK_910101')
            ,('ACK_XIS_900000000','ACK_XIS_900000000','ACK_XIS_900000000')
            ,('GGG_0000000','GGG_0000000','GGG_0000000')
            ,('ASC_VNA_303930','ASC_VNA_303930','ASC_VNA_303930')
            ,('ACK_393848489','ACK_393848489','ACK_393848489')
            ,('ACK_VNA_30303','ACK_VNA_30303','ACK_VNA_30303')
            ,('ACK_XPM_303030303030','ACK_XPM_303030303030','ACK_XPM_303030303030')
            ,('ACK_ACK_DOV_39393','ACK_VOD_39393','ACK_VOD_39393')
            ,('ZEBRA_0393930','ZEBRA_0393930','ZEBRA_0393930')
            ,('ZEBRA_393939_DOV','ZEBRA_393939_DOV','ZEBRA_393939_DOV')
            ,('ZEBRA_VNA_3930321','ZEBRA_VNA_3930321','ZEBRA_VNA_3930321')
            ,('ZEBRA_ACK_ACK_DOV_3934994','ZEBRA_ACK_VOD_3934994','ACK_VOD_3934994')
            ,('ZEBRA_ZEBRA_29393930','ZEBRA_ZEBRA_29393930','ZEBRA_29393930')
    )
    select org_value
        ,seq
        ,array_to_string(array_agg(part) within group (order by index), '_') as output
    from (
        select d.value as org_value
            ,f.seq
            ,f.index
            ,f.value as part
            ,case when part='ZEBRA' then 1
                when part='ACK' then 1
                else 0
             end bad_bit
            ,sum(bad_bit)over(partition by f.seq order by f.index desc) as c
        from data d, table(split_to_table(d.value,'_')) f
    )
    where c <= 1
    group by org_value, seq
    order by seq
    

    关于输入/输出期望值的好数据。如果你真的想用正则表达式来实现这一点,请编写一个使用完整的posix正则表达式的javascript UDF,然后你可以使用反向匹配。为什么
    ZEBRA_ACK_ACK_DOV_3934994
    转换为
    ZEBRA_ACK_VOD_3934994
    ?(a) 我以为你只想要输出中的一个
    ZEBRA
    ACK
    ,其次为什么
    DOV
    被翻译成
    VOD
    。我修正了这个问题,所以只有斑马或羚羊。2.应该是DOV。我错过了它,因为我正试图把这篇文章放在一起。@analytica我已经重新旋转它来应用你的新逻辑/解释。
    ORG_VALUE                SEQ    OUTPUT
    ACK_ACK_DOV_90000        1  ACK_DOV_90000
    ACK_910101               2  ACK_910101
    ACK_XIS_900000000        3  ACK_XIS_900000000
    GGG_0000000              4  GGG_0000000
    ASC_VNA_303930           5  ASC_VNA_303930
    ACK_393848489            6  ACK_393848489
    ACK_VNA_30303            7  ACK_VNA_30303
    ACK_XPM_303030303030     8  ACK_XPM_303030303030
    ACK_ACK_DOV_39393        9  ACK_DOV_39393
    ZEBRA_0393930            10 ZEBRA_0393930
    ZEBRA_393939_DOV         11 ZEBRA_393939_DOV
    ZEBRA_VNA_3930321        12 ZEBRA_VNA_3930321
    ZEBRA_ACK_ACK_DOV_3934994   13  ACK_DOV_3934994
    ZEBRA_ZEBRA_29393930     14 ZEBRA_29393930