【问题标题】:Regex extract in BigQuery issueBigQuery 问题中的正则表达式提取
【发布时间】:2019-07-24 09:20:12
【问题描述】:

我正在尝试通过对其使用 BigQuery 提取来简化 BigQuery 中的列,但我遇到了一些问题。

以下是我从中提取数据的两个示例:

dc_pre=CLXk_aigyOMCFQb2dwod4dYCZw;gtm=2wg7f1;gcldc=;gclaw=;gac=UA-5815571-8:;auiddc=;u1=OVERDRFT;u2=undefined ;u3=undefined;u4=undefined;u5=SSA;u6=undefined;u7=na;u8=undefined;u9=undefined;u10=undefined;u11=undefined;~oref=https://www.online.bank.co.za/onlineContent/ga_bridge.html

dc_pre=COztt4-tyOMCFcji7Qod440PCw;gtm=2wg7f1;gcldc=;gclaw=;gac=UA-5815571-8:;auiddc=;u1=DDA13;u2 =undefined;u3=undefined;u4=undefined;u5=SSA;u6=undefined;u7=na;u8=undefined;u9=undefined;u10=undefined;u11=undefined;~oref=https://www.online.support.co.za/onlineContent/ga_bridge.html

我想提取 ;u1=;u2

之间的部分

运行以下旧版 SQL 查询

SELECT

      Date(Event_Time),
      Activity_ID,
      REGEXP_EXTRACT(Other_Data, r'(?<=u1=)(.*\n?)(?=;u2)')
    FROM
      [sprt-data-transfer:dtftv2_sprt.p_activity_166401]
    WHERE
      Activity_ID in ('8179851')
      AND Site_ID_DCM NOT IN ('2134603','2136502','2539719','2136304','2134604','2134602','2136701','2378406') 
      AND Event_Time BETWEEN 1563746400000000 AND 1563832799000000

我得到了错误...

无法解析正则表达式“(?

这就是我的才华耗尽的地方,是因为我使用的是旧版 SQL 而导致的错误吗?或者是 REGEX 不支持的格式?

【问题讨论】:

  • 在纯正则表达式中它确实有效,但是在 BigQuery 中使用查询时它就无效了。
  • 也许你应该转义几个字符?
  • 这就是我的才华耗尽的地方 :) 我可以在孤立的情况下找到解决 Regex 的方法,而且我在 BigQuery 中还可以,但是将这两个世界结合起来导致了问题。
  • 如果输入字符串总是包含u1=[the string you want];u2..,为什么不能直接使用r'u1=(.*?);u2'?顺便说一句,考虑迁移到标准 SQL。

标签: sql regex google-bigquery


【解决方案1】:

刚刚尝试过,它工作正常,但启用了“标准 SQL”。

select
    other_data,
    regexp_extract(other_data, ';u1=(.+?);u2') as some_part
from
    unnest([
        'dc_pre=CLXk_aigyOMCFQb2dwod4dYCZw;gtm=2wg7f1;gcldc=;gclaw=;gac=UA-5815571-8:;auiddc=;u1=OVERDRFT;u2=undefined;u3=undefined;u4=undefined;u5=SSA;u6=undefined;u7=na;u8=undefined;u9=undefined;u10=undefined;u11=undefined;~oref=https://www.online.bank.co.za/onlineContent/ga_bridge.html',
        'dc_pre=COztt4-tyOMCFcji7Qod440PCw;gtm=2wg7f1;gcldc=;gclaw=;gac=UA-5815571-8:;auiddc=;u1=DDA13;u2=undefined;u3=undefined;u4=undefined;u5=SSA;u6=undefined;u7=na;u8=undefined;u9=undefined;u10=undefined;u11=undefined;~oref=https://www.online.support.co.za/onlineContent/ga_bridge.html'
    ]) as other_data

【讨论】:

  • 非常感谢!现在也在将我的所有查询切换到标准 SQL
【解决方案2】:

不使用正则表达式,但它仍然有效...

with test as (
select 1 as id, 'dc_pre=CLXk_aigyOMCFQb2dwod4dYCZw;gtm=2wg7f1;gcldc=;gclaw=;gac=UA-5815571-8:;auiddc=;u1=OVERDRFT;u2=undefined;u3=undefined;u4=undefined;u5=SSA;u6=undefined;u7=na;u8=undefined;u9=undefined;u10=undefined;u11=undefined;~oref=https://www.online.bank.co.za/onlineContent/ga_bridge.html' as my_str UNION ALL
select 2 as id, 'dc_pre=COztt4-tyOMCFcji7Qod440PCw;gtm=2wg7f1;gcldc=;gclaw=;gac=UA-5815571-8:;auiddc=;u1=DDA13;u2=undefined;u3=undefined;u4=undefined;u5=SSA;u6=undefined;u7=na;u8=undefined;u9=undefined;u10=undefined;u11=undefined;~oref=https://www.online.support.co.za/onlineContent/ga_bridge.html'
),
temp as (
  select 
    id,
    split(my_str,';') as items
  from test
),
flattened as (
  select
    id,
    split(i,'=')[SAFE_OFFSET(0)] as left_side,
    split(i,'=')[SAFE_OFFSET(1)] as right_side
  from temp
  left join unnest(items) i
)
select * from flattened
where left_side = 'u1'

【讨论】:

  • 为什么不直接使用正则表达式!?我认为它比使用拆分、连接、数组和过滤器更干净、更易于理解且更易于维护。 :)
  • 我基本同意你的观点,对于 1-off 查询,Regex 可能是更好的候选者。我通常会考虑管道、ETL/ELT 流程等。在我的回答中,您(和或您的数据下游的任何其他人)可以获得任何/所有查询参数。我也倾向于将此示例视为不仅仅是任何字符串,它显然是一个键值对字符串,我的示例将其转换为键值对数组并通过使用键使值可访问,保持精神和基础数据的意图。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-04
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 2012-07-25
相关资源
最近更新 更多