繁体   English   中英

PHP正则表达式替换网址路径中的单词

[英]PHP regex replace a word in url path

我正在尝试替换网址路径中的单词。

Fe host.com/path/to/find应该成为host.com/path/to/count

但即时通讯显然无法解决这个问题。

我试图让这个小组: (?:/count|/find)? 在字符串的末尾

并将其前面的所有内容替换为$1/count

但是总是在我尝试在(?:/count|/find)?之前得到零件(?:/count|/find)? 一部分,我搞砸了。

这是一个测试:

编辑: 所有键代表测试(缩小)URL。 所有值均代表预期结果。

因此,如果路径上没有“ / count”,则应添加它。

如果末尾有“ / count”,则无事可做。

如果路径末尾有“ / find”,则应更改为“ / count”。

如果网址中某处存在工作的“计数”(例如“ countleaveMeAlone”),则不应更改(ofc)。

$urls = [

    'http://foo-bar.host.com/entity/to'                => 'http://foo-bar.host.com/entity/to/count',
    'http://foo-bar.host.com/entity/to/'               => 'http://foo-bar.host.com/entity/to/count',
    'http://foo-bar.host.com/entity/to/find'           => 'http://foo-bar.host.com/entity/to/count',
    'http://foo-bar.host.com/entity/to/find/'          => 'http://foo-bar.host.com/entity/to/count/',
    'http://foo-bar.host.com/entity/to/find?some=foo'  => 'http://foo-bar.host.com/entity/to/count?some=foo',
    'http://foo-bar.host.com/entity/to/find/?foo=some' => 'http://foo-bar.host.com/entity/to/count/?foo=some',

    'http://foo-bar.host.com/entity/to/count'           => 'http://foo-bar.host.com/entity/to/count',
    'http://foo-bar.host.com/entity/to/count/'          => 'http://foo-bar.host.com/entity/to/count/',
    'http://foo-bar.host.com/entity/to/count?some=foo'  => 'http://foo-bar.host.com/entity/to/count?some=foo',
    'http://foo-bar.host.com/entity/to/count/?foo=some' => 'http://foo-bar.host.com/entity/to/count/?foo=some',

    'http://foo-bar.host.com/entity/toleaveMeAlone'                 => 'http://foo-bar.host.com/entity/toleaveMeAlone',
    'http://foo-bar.host.com/entity/to/leaveMeAlone'                => 'http://foo-bar.host.com/entity/to/leaveMeAlone',
    'http://foo-bar.host.com/entity/to/countleaveMeAlone'           => 'http://foo-bar.host.com/entity/to/countleaveMeAlone',
    'http://foo-bar.host.com/entity/to/count/leaveMeAlone'          => 'http://foo-bar.host.com/entity/to/count/leaveMeAlone',
    'http://foo-bar.host.com/entity/to/countleaveMeAlone?some=foo'  => 'http://foo-bar.host.com/entity/to/countleaveMeAlone?some=foo',
    'http://foo-bar.host.com/entity/to/count/leaveMeAlone?foo=some' => 'http://foo-bar.host.com/entity/to/count/leaveMeAlone?foo=some',
];

$format = "%-70s%-70s%s\r\n";
echo sprintf($format, 'TEST', 'EXPECT', 'SUCCESS');
foreach ($urls as $url => $expect) {
    $tmp = explode('?', $url);
    $url = rtrim($tmp[0], '/');
    $query = isset($tmp[1])
        ? $tmp[1]
        : '';

    /**
     * Pattern
     * /
     *      \A                  --start string
     *      (.*)                --get all before
     *      (?:/count|/find)?   --get optional "/find" or "/count"
     *      \z                  --end string
     * /
     */
    $url = preg_replace(
        "#\A(.*)(?:/count|/find)?\z#",
        '$1/count',
        $url
    );

    $url .= strlen($query)
        ? '?' . $query
        : '';

    echo sprintf($format, $url, $expect, var_export($url === $expect, true));
}

任何帮助表示赞赏

$urls = [
'http://foo-bar.host.com/entity/to'                => 'http://foo-bar.host.com/entity/to/count',
'http://foo-bar.host.com/entity/to/'               => 'http://foo-bar.host.com/entity/to/count',
'http://foo-bar.host.com/entity/to/find'           => 'http://foo-bar.host.com/entity/to/count',
'http://foo-bar.host.com/entity/to/find/'          => 'http://foo-bar.host.com/entity/to/count/',
'http://foo-bar.host.com/entity/to/find?some=foo'  => 'http://foo-bar.host.com/entity/to/count?some=foo',
'http://foo-bar.host.com/entity/to/find/?foo=some' => 'http://foo-bar.host.com/entity/to/count/?foo=some'];
foreach ($urls as $url => $expect) {   
$new_url = str_replace("find","count",$url);
echo $new_url."<br />";
}

模式:( 带有官方说明的模式/替换演示

~^([^?]+?)/?((?:(?:/count|leaveMeAlone)(*SKIP)(*FAIL))|(?:find/??)?)((?:(?<=find)/)?)((?:\?.*)?)$~

莱曼的故障:

  • ~起始模式定界符(不是斜杠,因此不需要在模式中转义斜杠)
  • ^匹配字符串的开头
  • ([^?]+?)捕获一个或多个非问号的字符(懒惰/非贪婪)
  • /? 匹配零或一个斜杠
  • (捕获...
    • (?:(?:/count|leaveMeAlone)(*SKIP)(*FAIL))如果失格整个字符串/countleaveMeAlone之前发现?
    • | 要么
    • (?:find/??)? (可选)捕获带有零或一个尾斜杠的发现(惰性)
  • ) ...结束捕获
  • ((?:(?<=find)/)?)如果在find之前添加零或一个斜杠
  • ((?:\\?.*)?)捕获URL的可选查询字符串部分
  • $匹配字符串的结尾
  • ~结束模式定界符

代码:( 演示

$urls = [
    'http://foo-bar.host.com/entity/to'                => 'http://foo-bar.host.com/entity/to/count',
    'http://foo-bar.host.com/entity/to/'               => 'http://foo-bar.host.com/entity/to/count',
    'http://foo-bar.host.com/entity/to/find'           => 'http://foo-bar.host.com/entity/to/count',
    'http://foo-bar.host.com/entity/to/find/'          => 'http://foo-bar.host.com/entity/to/count/',
    'http://foo-bar.host.com/entity/to/find?some=foo'  => 'http://foo-bar.host.com/entity/to/count?some=foo',
    'http://foo-bar.host.com/entity/to/find/?foo=some' => 'http://foo-bar.host.com/entity/to/count/?foo=some',

    'http://foo-bar.host.com/entity/to/count'           => 'http://foo-bar.host.com/entity/to/count',
    'http://foo-bar.host.com/entity/to/count/'          => 'http://foo-bar.host.com/entity/to/count/',
    'http://foo-bar.host.com/entity/to/count?some=foo'  => 'http://foo-bar.host.com/entity/to/count?some=foo',
    'http://foo-bar.host.com/entity/to/count/?foo=some' => 'http://foo-bar.host.com/entity/to/count/?foo=some',

    'http://foo-bar.host.com/entity/toleaveMeAlone'                 => 'http://foo-bar.host.com/entity/toleaveMeAlone',
    'http://foo-bar.host.com/entity/to/leaveMeAlone'                => 'http://foo-bar.host.com/entity/to/leaveMeAlone',
    'http://foo-bar.host.com/entity/to/countleaveMeAlone'           => 'http://foo-bar.host.com/entity/to/countleaveMeAlone',
    'http://foo-bar.host.com/entity/to/count/leaveMeAlone'          => 'http://foo-bar.host.com/entity/to/count/leaveMeAlone',
    'http://foo-bar.host.com/entity/to/countleaveMeAlone?some=foo'  => 'http://foo-bar.host.com/entity/to/countleaveMeAlone?some=foo',
    'http://foo-bar.host.com/entity/to/count/leaveMeAlone?foo=some' => 'http://foo-bar.host.com/entity/to/count/leaveMeAlone?foo=some',
];

$pattern='~^([^?]+?)/?((?:(?:/count|leaveMeAlone)(*SKIP)(*FAIL))|(?:find/??)?)((?:(?<=find)/)?)((?:\?.*)?)$~';
$replace='$1/count$3$4';
foreach($urls as $url=>$expected){
    echo "$url\n";                                   // your input
    echo preg_replace($pattern,$replace,$url),"\n";  // my output
    echo "$expected\n\n";                            // your expected output
}

输出:

http://foo-bar.host.com/entity/to
http://foo-bar.host.com/entity/to/count
http://foo-bar.host.com/entity/to/count

http://foo-bar.host.com/entity/to/
http://foo-bar.host.com/entity/to/count
http://foo-bar.host.com/entity/to/count

http://foo-bar.host.com/entity/to/find
http://foo-bar.host.com/entity/to/count
http://foo-bar.host.com/entity/to/count

http://foo-bar.host.com/entity/to/find/
http://foo-bar.host.com/entity/to/count/
http://foo-bar.host.com/entity/to/count/

http://foo-bar.host.com/entity/to/find?some=foo
http://foo-bar.host.com/entity/to/count?some=foo
http://foo-bar.host.com/entity/to/count?some=foo

http://foo-bar.host.com/entity/to/find/?foo=some
http://foo-bar.host.com/entity/to/count/?foo=some
http://foo-bar.host.com/entity/to/count/?foo=some

http://foo-bar.host.com/entity/to/count
http://foo-bar.host.com/entity/to/count
http://foo-bar.host.com/entity/to/count

http://foo-bar.host.com/entity/to/count/
http://foo-bar.host.com/entity/to/count/
http://foo-bar.host.com/entity/to/count/

http://foo-bar.host.com/entity/to/count?some=foo
http://foo-bar.host.com/entity/to/count?some=foo
http://foo-bar.host.com/entity/to/count?some=foo

http://foo-bar.host.com/entity/to/count/?foo=some
http://foo-bar.host.com/entity/to/count/?foo=some
http://foo-bar.host.com/entity/to/count/?foo=some

http://foo-bar.host.com/entity/toleaveMeAlone
http://foo-bar.host.com/entity/toleaveMeAlone
http://foo-bar.host.com/entity/toleaveMeAlone

http://foo-bar.host.com/entity/to/leaveMeAlone
http://foo-bar.host.com/entity/to/leaveMeAlone
http://foo-bar.host.com/entity/to/leaveMeAlone

http://foo-bar.host.com/entity/to/countleaveMeAlone
http://foo-bar.host.com/entity/to/countleaveMeAlone
http://foo-bar.host.com/entity/to/countleaveMeAlone

http://foo-bar.host.com/entity/to/count/leaveMeAlone
http://foo-bar.host.com/entity/to/count/leaveMeAlone
http://foo-bar.host.com/entity/to/count/leaveMeAlone

http://foo-bar.host.com/entity/to/countleaveMeAlone?some=foo
http://foo-bar.host.com/entity/to/countleaveMeAlone?some=foo
http://foo-bar.host.com/entity/to/countleaveMeAlone?some=foo

http://foo-bar.host.com/entity/to/count/leaveMeAlone?foo=some
http://foo-bar.host.com/entity/to/count/leaveMeAlone?foo=some
http://foo-bar.host.com/entity/to/count/leaveMeAlone?foo=some

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM