BigQuery Regex_Replace 重复子字符串的第一个实例

Posted

技术标签:

【中文标题】BigQuery Regex_Replace 重复子字符串的第一个实例【英文标题】:BigQuery Regex_Replace first instance of duplicated substring 【发布时间】:2017-11-28 16:33:10 【问题描述】:

我知道有很多关于惰性正则表达式匹配的问题,但我见过的解决方案都没有奏效。问题来了:

我的 BigQuery 结果中的一些地址如下所示:

www.example.comwww.example.com/path/to/page
apply.example.comapply.example.com/eapp/

我想去掉重复的部分得到

www.example.com/path/to/page
apply.example.com/eapp/

我试过像这样使用REGEX_REPLACE()

REGEXP_REPLACE(raw.query.tidy_Landing, r'(.*?)\.com','') AS Landing_Page

但这仍然会找到两个匹配项并返回

/path/to/page
/eapp/

我的正则表达式有什么问题?

【问题讨论】:

【参考方案1】:

#standardSQL
WITH t AS (
  SELECT 'www.example.comwww.example.com/path/to/page' str UNION ALL
  SELECT 'apply.example.comapply.example.com/eapp/'
)
SELECT str, REGEXP_REPLACE(str, r'^(.*?\.com)', '') fix
FROM t

输出是

str                                             fix  
www.example.comwww.example.com/path/to/page     www.example.com/path/to/page  
apply.example.comapply.example.com/eapp/        apply.example.com/eapp/   

【讨论】:

啊,我明白了。 ^ 确保它从字符串的开头查找并在第一次匹配后停止。否则它会继续返回匹配,即使它是惰性的并且它们是不同的。【参考方案2】:

我想看看是否可以在没有正则表达式的情况下执行此操作,尽管它最终会有点冗长:) 这个答案假设地址总是重复并以 .com 结尾。假设是这样的话,应该可以使用SPLIT来提取你感兴趣的部分:

SELECT
  CONCAT(
    SPLIT(text, '.com')[OFFSET(0)],
    '.com',
    SPLIT(text, '.com')[OFFSET(2)]
  ) AS Landing_Page
FROM (
  SELECT 'www.example.comwww.example.com/path/to/page' AS text UNION ALL
  SELECT 'apply.example.comapply.example.com/eapp/'
);

如果希望查询能够容忍不重复的地址,可以稍作修改:

SELECT
  (
    SELECT 
      CONCAT(
        parts[OFFSET(0)],
        '.com',
        parts[OFFSET(ARRAY_LENGTH(parts) - 1)]
      )
    FROM (SELECT SPLIT(text, '.com') AS parts)
  ) AS Landing_Page
FROM (
  SELECT 'www.example.comwww.example.com/path/to/page' AS text UNION ALL
  SELECT 'apply.example.comapply.example.com/eapp/' UNION ALL
  SELECT 'www.example.com/path/to/page'
);

更进一步,您可以将逻辑提取到 UDF 中:

CREATE TEMP FUNCTION GetLandingPage(text STRING) AS (
  (
    SELECT 
      CONCAT(
        parts[OFFSET(0)],
        '.com',
        parts[OFFSET(ARRAY_LENGTH(parts) - 1)]
       )
    FROM (SELECT SPLIT(text, '.com') AS parts)
  )
);

SELECT
  GetLandingPage(text) AS Landing_Page
FROM (
  SELECT 'www.example.comwww.example.com/path/to/page' AS text UNION ALL
  SELECT 'apply.example.comapply.example.com/eapp/' UNION ALL
  SELECT 'www.example.com/path/to/page'
);

【讨论】:

这很酷;总是准备好 UDF 解决方案。肯定会把它藏起来做更多的实验,谢谢!

以上是关于BigQuery Regex_Replace 重复子字符串的第一个实例的主要内容,如果未能解决你的问题,请参考以下文章

查询 Bigquery 重复字段

BigQuery:展平两个重复的列

Bigquery:检查流期间的重复项

重复字段的 BigQuery 记录

在 BigQuery 中嵌套多个重复字段

BigQuery:如何从重复记录中仅提取某些字段作为另一个重复字段