【问题标题】:BigQuery Regex_Replace first instance of duplicated substringBigQuery Regex_Replace 重复子字符串的第一个实例
【发布时间】: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/

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

【问题讨论】:

    标签: regex google-bigquery


    【解决方案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 解决方案。肯定会把它藏起来做更多的实验,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-15
    • 2013-12-17
    • 1970-01-01
    • 2012-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多