代码之家  ›  专栏  ›  技术社区  ›  Joyce Babu

重置位置指针以替换所有出现的模式,直到使用preg_replace在单个步骤中使用分隔符

  •  0
  • Joyce Babu  · 技术社区  · 8 年前

    preg_replace 要替换模式的所有出现直到指定分隔符?

    我想替换一个模式的多次出现,而不是替换分隔符之前的整个字符串。

    在不拆线的情况下,一步就能做到吗? 是否可以指定在每次替换后将位置指针重置为起始位置?我能用lookahead来实现这个目标吗?

    例如,我想替换 // 在以下URL中,直到 ? 性格。

    https://www.example.com//abc/def/ghi/?jkl=mno//pqr
    https://www.example.com//abc/def//ghi/?jkl=mno//pqr
    https://www.example.com//abc//def//ghi/?jkl=mno//pqr
    

    预期产量:

    https://www.example.com/abc/def/ghi/?jkl=mno//pqr
    

    请注意

    • //
    • 任何发生 // 在分隔符之后 没有被碰过。
    • 这可以通过先拆分字符串来完成。但我正在寻找一个正则表达式唯一的解决方案。
    2 回复  |  直到 8 年前
        1
  •  3
  •   revo shanwije    8 年前

    目前公认的答案足以作为解决方案,但也存在一些可能在不久的将来引发问题的问题:

    • 真正地 在到达第一次出现的 ?

    • https 协议(需要手动添加其他协议以进行查找)。

    (^\w+:/|\G[^?/]*)/+
    

    上面的regex调用 \G 它匹配上一个匹配结束的位置。意思是当 ?

    live demo here

    echo preg_replace('@(^\w+:/|\G[^?/]*)/+@', '$1/', $url);
    

    请注意,您可能需要 (?!^) 之前 \克 ://example.com

        2
  •  3
  •   Nick SamSmith1986    8 年前

    你可以使用积极的展望来确保 // 后面跟着一个 ? :

    $urls = array('https://www.example.com//abc/def/ghi/?jkl=mno//pqr',
    'https://www.example.com//abc/def//ghi/?jkl=mno//pqr',
    'https://www.example.com//abc//def//ghi/?jkl=mno//pqr');
    foreach ($urls as $url)
        echo preg_replace('#//(?=.*\?)#', '/', $url) . "\n";
    

    输出:

    https:/www.example.com/abc/def/ghi/?jkl=mno//pqr
    https:/www.example.com/abc/def/ghi/?jkl=mno//pqr
    https:/www.example.com/abc/def/ghi/?jkl=mno//pqr
    

    正如@revo所指出的,这也将删除 // https:

    foreach ($urls as $url)
        echo preg_replace('#(?<!https:)//(?=.*\?)#', '$1/', $url) . "\n";
    

    输出:

    https://www.example.com/abc/def/ghi/?jkl=mno//pqr
    https://www.example.com/abc/def/ghi/?jkl=mno//pqr
    https://www.example.com/abc/def/ghi/?jkl=mno//pqr