【问题标题】:Using BQ regex to extract elements with "strings" as delimiters使用 BQ 正则表达式提取以“字符串”为分隔符的元素
【发布时间】:2021-05-20 19:49:54
【问题描述】:

我在构建 BQ 正则表达式时遇到问题,该表达式从一组具有可变分隔符的文本中提取给定项目,采用 Key = Value 表达式的形式。

我正在谈论的字符串示例是:

house = long island && house : @New Amsterdam @@ house = Texas

令牌分隔符和密钥分隔符是已知的。 在这种情况下:

Token delimiters = {' = ' |  ' : @'}
key delimiters =  { && | @@ }

我想要结果

long island
New Amsterdam
Texas

REGEXP_EXTRACT_ALL("house = long island && house : @New Amsterdam", regex);

我在使用正则表达式时遇到问题: house(( = )|( : @))[^(&&|@@)]*(&&|@@)

【问题讨论】:

    标签: sql regex google-bigquery


    【解决方案1】:

    使用

    REGEXP_EXTRACT_ALL(txt, 'house\W*([^&@:]*[^&@:\s])')
    

    regex proof

    解释

    --------------------------------------------------------------------------------
      house                    'house'
    --------------------------------------------------------------------------------
      \W*                      non-word characters (all but a-z, A-Z, 0-
                               9, _) (0 or more times (matching the most
                               amount possible))
    --------------------------------------------------------------------------------
      (                        group and capture to \1:
    --------------------------------------------------------------------------------
        [^&@:]*                  any character except: '&', '@', ':' (0
                                 or more times (matching the most amount
                                 possible))
    --------------------------------------------------------------------------------
        [^&@:\s]                 any character except: '&', '@', ':',
                                 whitespace (\n, \r, \t, \f, and " ")
    --------------------------------------------------------------------------------
      )                        end of \1
    

    【讨论】:

      【解决方案2】:

      考虑下面的例子

      with t as (
        select 'house = long island && house : @New Amsterdam @@ house = Texas' txt  
      )
      select result
      from t,
      unnest(split(regexp_replace(txt, r'[=&:@]', ''), 'house')) result
      where result != ''    
      

      有输出

      或更通用的解决方案

      with t as (
        select 'house = long island && house : @New Amsterdam @@ house = Texas' txt  
      )
      select 
        arr[offset(0)] as key,
        arr[offset(1)] as value
      from t,
      unnest(split(regexp_replace(regexp_replace(txt, r' && | @@ ', '|||'), r' = | : @', '&&&'), '|||')) kv,
      unnest([struct(split(kv, '&&&') as arr)])
      

      有输出

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-17
        • 1970-01-01
        相关资源
        最近更新 更多