代码之家  ›  专栏  ›  技术社区  ›  SeanW333

mysql:为什么在使用replace时url不匹配?

  •  -2
  • SeanW333  · 技术社区  · 7 年前

    我的处境:

    我的url在一个包含博客文章的字段中。该url以转义字符存储在我的数据库中。我现在的任务是用“http s”url替换一些已经插入的“http”url,但是replace既不匹配原始url,也不匹配转义url。我不能只替换“http:”的每个实例,因为我只想影响每个帖子中的某些链接,而不是每个链接。

    我对sql和replace都很熟悉,所以我不只是问replace如何工作和如何使用它。这里的另一个用户已经在他的环境中测试了我的查询,它们可以工作。所以,在我的配置中一定有一些东西阻止了查询按预期运行。

    我已经在这个网站和谷歌搜索了几个小时,没有发现任何具体解决我的问题。我尝试过的每件事都包含在下面,如果有其他我应该尝试的事情,我不知道那是什么,我也没有发现任何建议/帖子/评论建议做任何不同的事情。

    示例URL:

    http://test01.mysite.com
    

    存储在数据库中:

    http:\/\/test01.mysite.com
    

    重新创建情景的代码:

    DROP TABLE IF EXISTS test_posts;
    CREATE TABLE IF NOT EXISTS test_posts (
        id int NOT NULL AUTO_INCREMENT,
        post_content longtext NOT NULL,
        PRIMARY KEY (id)
    )
    
    INSERT INTO 
        test_posts
            (post_content)
        VALUES 
            ('content content content <a href="http:\\/\\/test01.mysite.com">Link I want to change</a> content content content <a href="http:\\/\\/someothersite.com">Link I don\'t want to change</a> content content content <a href="http:\\/\\/test01.mysite.com">Link I want to change</a> content content content <a href="http:\\/\\/someothersite.com">Link I don\'t want to change</a>');
    

    如果我跑

    UPDATE
        test_posts
    SET
        post_content = REPLACE(post_content, 'http://test01.mysite.com', 'https://test01.mysite.com');
    

    UPDATE
        test_posts
    SET
        post_content = REPLACE(post_content, 'http:\/\/test01.mysite.com', 'https://test01.mysite.com');
    

    零记录受到影响。

    出于测试目的,我运行了以下返回0行的查询。

    SELECT
        *
    FROM
        test_posts
    WHERE
        post_content LIKE '%http://test01.mysite.com%'
        OR
        post_content LIKE '%http:\/\/test01.mysite.com%'
        OR
        post_content LIKE '%http:\\/\\/test01.mysite.com%'
        OR
        post_content LIKE 'http:%/%/test01.mysite.com%';
    

    如果我跑:

    SELECT 
        *
    FROM
        test_posts 
    WHERE 
        post_content LIKE '%http:_/_/test01.mysite.com%'
    

    它确实返回匹配项,但这并不能解决在使用update/replace时如何匹配的实际问题。

    我试过两台不同的服务器,结果都一样。

    我尝试了以下引擎/排序规则组合,所有这些组合都返回相同的0记录结果:

    Myisam/拉丁语瑞典语

    myisam/utf8mb4_unicode_ci码

    Innodb/拉丁语瑞典语

    innodb/utf8mb4_unicode_ci接口

    任何人都知道我如何编写这些查询,以便replace能够找到与这些url的匹配项,或者我的数据库或phpmyadmin中的哪些设置可能导致查询返回/影响0行?

    4 回复  |  直到 6 年前
        1
  •  1
  •   Joop Eggen    7 年前

    我认为反斜杠必须在mysql中转义

    field_name LIKE 'http:\\/\\/test01.mysite.com%'
    

    当然可以使用单字符通配符 _ _

    field_name LIKE 'http:_/_/test01.mysite.com%'
    

    或者对于这两种情况:可选的反斜杠:

    field_name LIKE 'http:%/%/test01.mysite.com%'
    
        2
  •  1
  •   SeanW333    7 年前

    以下工作:

    UPDATE
        test_posts
    SET 
        post_content = REPLACE(post_content, 'http:\\/\\/test01.mysite.com', 'https://test01.mysite.com');
    

    如果有人能向我解释为什么这些组合使用replace,而不是like,我真的很想知道。谢谢!

        3
  •  0
  •   Red Boy    7 年前

    没有原因,如果运行正常,查询将无法工作,还有其他问题,您可能会在此处丢失。

    UPDATE test1 SET name_1 = REPLACE(name_1, 'http:\/\/test01.mysite.com', 'https://test01.mysite.com')

    很好地工作并且完成了重新分解 \/ 具有 / . 请参阅附带的屏幕截图,

    enter image description here

    您可能还有其他问题,请检查并更新问题(如果有)。

    评论后编辑

    如果URL中有更多数据点,请更改如下查询。

    UPDATE test1 SET name_1 = REPLACE(name_1, '\/', '/')

    以上将取代所有发生的 \/ 具有 / 是的。

        4
  •  0
  •   Joop Eggen    7 年前

    作为 \\ 无法表示/转义反斜杠,请使用 regular expression 功能:

    REGEXP_LIKE('.*http:\\/\\/test01\.mysite.com.*')
    REGEXP_REPLACE(field, 'http:\\/\\/', 'http://')
    

    在这里 \\ 应该工作。