BigQuery 问题中的正则表达式提取

Posted

技术标签:

【中文标题】BigQuery 问题中的正则表达式提取【英文标题】:Regex extract in BigQuery issue 【发布时间】: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 不支持的格式?

【问题讨论】:

作品:regex101.com/r/07urzB/1 在纯正则表达式中它确实有效,但是在 BigQuery 中使用查询时它就无效了。 也许你应该转义几个字符? 这就是我的才华耗尽的地方 :) 我可以在孤立的情况下找到解决 Regex 的方法,而且我在 BigQuery 中还可以,但是将这两个世界结合起来导致了问题。 如果输入字符串总是包含u1=[the string you want];u2..,为什么不能直接使用r'u1=(.*?);u2'?顺便说一句,考虑迁移到标准 SQL。 【参考方案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 流程等。在我的回答中,您(和或您的数据下游的任何其他人)可以获得任何/所有查询参数。我也倾向于将此示例视为不仅仅是任何字符串,它显然是一个键值对字符串,我的示例将其转换为键值对数组并通过使用键使值可访问,保持精神和基础数据的意图。

以上是关于BigQuery 问题中的正则表达式提取的主要内容,如果未能解决你的问题,请参考以下文章

BigQuery 正则表达式提取

拆分字符串,提取并添加到另一列正则表达式 BIGQUERY

BigQuery 正则表达式提取两个子字符串之间的字符串

正则表达式:在 Google Bigquery 中提取正斜杠后的所有内容?

在 Bigquery 中看到“数字 + 一个字母 + [逗号或空格]”后提取字符串的正则表达式

Bigquery 中数字+字母组合的正则表达式