【问题标题】:How to pass multiple delimeters in substring_index如何在 substring_index 中传递多个分隔符
【发布时间】:2019-04-13 13:45:52
【问题描述】:

我想查询 https:// 或 http:// 及其后面的第一个分隔符之间的字符串。例如,如果该字段包含:

https://google.com/en/
https://www.yahoo.com?en/

我想得到:

google.com
www.yahoo.com

将捕获/ 的初始查询仅包含两个子字符串索引,如下所示:

SELECT substring_index(substring_index(mycol,'/',3),'://',-1)
FROM mytable;

现在我发现 URL 可能包含多个分隔符。我希望我的状态能够捕获多个分隔符的可能性(每个分隔符都是一个单独的字符):

:/?#[]@!$&'()*+,;=

如何在我的声明中做到这一点?我尝试了this solution,但最终结果由于语法错误而无法执行命令,而我确信我遵循了解决方案。谁能帮我正确构建查询以捕获我上面列出的所有分隔符?

我在 Ubuntu 18.04 上使用 MySQL workbecnh 6.3。

编辑:

在第一个 URL 示例中进行了一些更正。

【问题讨论】:

    标签: mysql sql database substring relational-database


    【解决方案1】:

    首先,请注意https://www.yahoo.com?en/ 似乎不太可能是 URL,因为它在查询字符串中包含一个路径分隔符。无论如何,如果您使用的是 MySQL 8+,请考虑使用其正则表达式功能。 REGEXP_REPLACE 函数在这里很有帮助,使用以下模式:

    https?://([A-Za-z_0-9.-]+).*
    

    示例查询:

    WITH yourTable AS (
        SELECT 'https://www.yahoo.com?en/' AS url UNION ALL
        SELECT 'no match'
    )
    
    SELECT
        REGEXP_REPLACE(url, 'https?://([A-Za-z_0-9.-]+).*', '$1') AS url
    FROM yourTable
    WHERE url REGEXP 'https?://[^/]+';
    

    Demo

    术语$1 指的是正则表达式模式中的第一个捕获 组。显式捕获组由括号中的数量表示。在这种情况下,这里是捕获组(在下面突出显示):

    https?://([A-Za-z_0-9.-]+).*
              ^^^^^^^^^^^^^^^
    

    即捕获组是URL路径的第一部分,包括域、子域等

    【讨论】:

    • https://www.yahoo.com?en/ seems like an unlikely URL。这只是一个例子。但我有包含此类语法或类似语法的大型数据集..
    • 很好。我的回答应该处理你所有的情况(我认为)。
    • 但域名可以包含数字和破折号。您的 [A-Za-z_.]+ 没有捕捉到这一点。
    • 好点,我更新了我的正则表达式。只需拨打REGEXP_REPLACE,您就应该可以摆脱困境。
    • 和下划线也可以在域名中使用。抱歉,我不知道,但 search 现在说它们是合法的。
    【解决方案2】:

    在 MySQL 8+ 中,这应该可以工作:

    SELECT regexp_replace(regexp_substr(mycol, '://[a-zA-Z0-9_.]+[/:?]'), '[^a-zA-Z0-9_.]', '')
    FROM (SELECT 'https://google.com/en' as mycol union all
          SELECT 'https://www.yahoo.com?en'
         ) x
    

    在旧版本中,这更具挑战性,因为无法搜索字符串类。

    一种蛮力方法是:

    select (case when substring_index(mycol, '://', -1) like '%/%'
                 then substring_index(substring_index(mycol, '://', -1), '/', 1)
                 when substring_index(mycol, '://', -1) like '%?%'
                 then substring_index(substring_index(mycol, '://', -1), '?', 1)
                 . . .   -- and so on for each character
                 else substring_index(mycol, '://', -1) 
            end) as what_you_want
    

    [a-zA-Z0-9_.] 旨在成为您域名的有效字符类。

    【讨论】:

    • 我不明白:order versions 中的意思是 older versions?无论如何,我使用的是6.3,所以没关系。但是捕获域名字符的挑战。它们不仅仅是字母字符。如果我是正确的,它们包含数字和破折号-
    • 你确定LIKE 中的? 字符前面应该是` as you write %\?%` 我查看了LIKE 中的特殊字符here 但似乎只有@ 987654332@ 和 _ 应该被转义?如果我错了,请纠正我?
    • @user9371654 。 . . ? 不需要为 LIKE 转义。
    猜你喜欢
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 2020-12-17
    • 2021-10-17
    • 2020-01-08
    • 1970-01-01
    • 2021-12-04
    • 2018-04-08
    相关资源
    最近更新 更多