【问题标题】:BQSQLException: Cannot parse regular expression: invalid perl operator: see full error in post as title cannot contain certain characters)BQSQLException:无法解析正则表达式:无效的 perl 运算符:查看帖子中的完整错误,因为标题不能包含某些字符)
【发布时间】:2021-07-01 16:17:43
【问题描述】:

请在本文末尾找到虚拟数据和我尝试的解决方案。

我在过去几天开始学习 REGEX,并正在创建一个 REGEX 以从我的数据集中排除任何私有 IP 地址。我的数据集有一列 url,它显示了公司从哪个 IP 地址执行了操作。此列包含url 格式的各种IP 地址。

我创建了一个查询,它应该只输出非本地 IP 地址(这是 URL 的一部分。我的查询如下:

WITH table_1 AS(

SELECT 'http://localhost:9999' AS url UNION ALL
SELECT 'https://localhost:0000' AS url UNION ALL
SELECT 'http://stackoverflow.com/challenge' AS url UNION ALL
SELECT 'https://arseniyaskingquestion.ru/SO' AS url 

)

SELECT url
FROM table_1
WHERE url NOT IN (SELECT DISTINCT url
                  FROM table_1
                  WHERE REGEXP_CONTAINS(url, r'((http(s)?):\/\/)(((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\.(?!$)|$)){4}$|(.*\.local)|(.*local\.)|(.*localhost)|(.*\.internal)|(.*csb.)|(.*codesandbox)|(.*lvh\.me)|(.*.ngrok.)|(.*nip\.io)|(.*.test)).*'))
ORDER BY url DESC

当我运行此查询时,我收到以下错误消息:BQSQLException: Cannot parse regular expression: invalid perl operator: (?!

我搜索了 StackOverflow 并注意到 1 个解决方案 here,但我无法使用 REGEXP_REPLACE 成功实施它 - 在我尝试实施此方案时以及阅读 Google Big Query 文档后,我不断收到其他错误。

从我的代码 sn-p 中可以看出,我试图仅输出非本地 IP 地址(它们是完整 url 链接的一部分)。因此,预期的输出是:

                url
----------------------------------
http://stackoverflow.com/challenge
https://arseniyaskingquestion.ru/SO

【问题讨论】:

    标签: regex google-bigquery


    【解决方案1】:

    LIKE 子句不合适吗?

    WHERE LOWER(url) NOT LIKE '%localhost%'
    

    您的正则表达式的主要问题是使用了否定前瞻(?!$)

    Google BigQuery 使用re2,它忽略了对环视的支持。

    在 regex101 中,您应该使用 Golang 选项开发您的正则表达式,因为它是基于 re2 的。请参阅https://regex101.com/r/HAV5J1/1/,它将解释您的正则表达式失败的原因。


    此外,您的子查询似乎非常低效:

    WHERE url NOT IN (SELECT DISTINCT url
                      FROM table_1
                      WHERE REGEXP_CONTAINS(url, r'((http(s)?):\/\/)(((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\.(?!$)|$)){4}$|(.*\.local)|(.*local\.)|(.*localhost)|(.*\.internal)|(.*csb.)|(.*codesandbox)|(.*lvh\.me)|(.*.ngrok.)|(.*nip\.io)|(.*.test)).*'))
    

    不能浓缩成:

    WHERE NOT REGEXP_CONTAINS(url, r'MY_REGEX')
    

    或:

    WHERE REGEXP_CONTAINS(url, r'MY_REGEX') = false
    

    我没有使用 BigQuery 的经验。

    【讨论】:

    • Localhost 不是我要删除的唯一内容。正如你在我的 REGEX 中看到的,很多东西都被排除在外。我可以使用许多 LIKE 语句,但出于学习的目的,我有目的地尝试使用 REGEX 执行此查询。因此,正在寻找与 REGEX 相关的解决方案。
    • @Arsik36 您需要提供更大的数据集,其中包含应该和不应该匹配的事物。我对为什么需要(?!$) 感到困惑。您的正则表达式并不完全易于阅读...
    • @Arsik36 关于您构建的值得称道的正则表达式,我想说您绝对应该在 regex101 上多玩一些,因为亲身实践并立即获得反馈是学习正则表达式的最佳方式。如果您想避免将来出现问题,请通过他们的documentation 了解支持的语法。
    【解决方案2】:

    您的正则表达式包含前瞻,而 RE2 不支持前瞻。

    如果您对自己的模式感到满意,并且只需要修复该前瞻问题,则可以打开 IP 匹配部分并使用

    https?:\/\/((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){4}$|.*\.local|.*local\.|.*localhost|.*\.internal|.*csb.|.*codesandbox|.*lvh\.me|.*.ngrok.|.*nip\.io|.*.test).*
    

    请参阅RE2 regex demo

    详情请见this IP matching regex page

    【讨论】:

      猜你喜欢
      • 2023-01-02
      • 2019-04-05
      • 2011-05-05
      • 2022-01-17
      • 1970-01-01
      • 2022-11-30
      • 2014-01-27
      • 1970-01-01
      • 2023-03-25
      相关资源
      最近更新 更多