【问题标题】:Redshift Extract String Between Two Patterns (regexp_substr)两个模式之间的 Redshift 提取字符串 (regexp_substr)
【发布时间】:2018-11-23 06:35:26
【问题描述】:

我正在尝试提取出现在deviceSerialNumber= 之后的文本,直到出现& 或字符串的结尾。数据看起来像

someddata&=somedataagain&deviceSerialNumber=device12345&anotherField=moreData someddata&=somedataagain&deviceSerialNumber=deviceabcd

我试过了

REGEXP_SUBSTR(session_tags || '&', 'deviceSerialNumber(.*)&') from table

但是,这会返回所有文本,直到最后一个 &(这是字符串的结尾,因为我附加了一个 & 用于模式匹配目的)。如何修改此正则表达式以仅提取文本直到第一个 &

【问题讨论】:

    标签: sql regex amazon-web-services amazon-redshift


    【解决方案1】:

    使用出现参数

    REGEXP_SUBSTR(session_tags, 'deviceSerialNumber=(.+?)&',1,1) from table
    

    或者

    REGEXP_SUBSTR(session_tags,(?<=deviceSerialNumber=)(.*?)(?=&)) from table
    

    .* 将匹配到最后一个 &,.*? 将匹配到第一个 &

    【讨论】:

    • 嗯,这看起来很有希望,但它似乎仍在提取所有文本,直到最后出现 &amp;
    • deviceSerialNumber=(.+?)& 应该这样做。您可能必须在最终选择中使用替换 deviceSerialNumber=。
    • 现在,我收到了 Invalid preceding regular expression prior to repetition operator 错误。当我尝试网络上的其他解决方案时,我很早就得到了它。想知道这是否与红移实现有关
    【解决方案2】:

    找到了一个 hack 解决方案,该解决方案涉及两个级别的查询,以绕过必须使用 regexp_subtr。内部查询使用substringposition 提取deviceSerialNumber 标记之后的所有文本。外部查询使用相同的两个函数来截断下一个&amp;之后的任何文本

    select substring(pre_serial_num, 1, position('&' in pre_device_id || '&') - 1) as device_id
    from
        (select substring(session_tags,position('deviceSerialNumber' in session_tags) + 20, 40) as pre_device_id 
        from table) a
    

    例如内部查询需要

    someddata&=somedataagain&deviceSerialNumber=device12345&anotherField=moreData

    someddata&=somedataagain&deviceSerialNumber=deviceabcd

    并去掉设备序列号标签前的文字给你

    device12345&anotherField=moreData

    deviceabcd

    然后第二个查询去掉设备序列号标签后的文本给你

    deviceSerialNumber=device12345

    deviceSerialNumber=deviceabcd

    【讨论】:

      【解决方案3】:

      我遇到了与regexp_substr 相同的Invalid preceding regular expression prior to repetition operator

      我最终确定的工作是两个嵌套的split_parts:

      select
      params, 
      split_part(split_part(params, 'deviceSerialNumber=', 2), '&', 1)
      from (
          select 'someddata&=somedataagain&deviceSerialNumber=device12345&anotherField=moreData' as params
          union all
          select 'someddata&=somedataagain&deviceSerialNumber=deviceabcd' as params
      ) tmp
      

      【讨论】:

        【解决方案4】:

        我知道回复晚了,但这里有一个对我有用的解决方案。

        select regexp_substr(
            'someddata&=somedataagain&deviceSerialNumber=device12345&anotherField=moreData ', 
            'deviceSerialNumber=(.*)&', 0, 1, 'e');
        

        【讨论】:

        • 这是正确的解决方案(即使用 e 参数匹配子表达式)。不幸的是,这个答案被埋在别人后面。
        • 你能告诉我,我如何在第一个'&'停止而不让它结束?
        猜你喜欢
        • 1970-01-01
        • 2020-04-19
        • 2023-02-10
        • 1970-01-01
        • 2013-05-28
        • 1970-01-01
        • 1970-01-01
        • 2014-05-20
        • 1970-01-01
        相关资源
        最近更新 更多