给定 html 页面内的一些 url,我想替换一些 url,如下所示:
示例网址:
https://example.com/cost-center/sub-one/article1
从那个文本中,我想将 /cost-center/
和网址最后一部分 (article1
) 之间的文本替换为另一个文本 (test
)
这意味着上面的网址将被转换为:
https://example.com/cost-center/test/article1
。
就我而言,
/cost-center/
之后可以有更多部分,并且网址可以以斜杠结尾,也可以在引号内,如下例所示:
https://example.com/cost-center/sub-one/sub-two/article-3/
https://example.com/cost-center/sub-one/sub-three/article-4
https://example.com/cost-center/sub-1/sub-two/sub-three/article-5/
'https://example.com/cost-center/sub-one/sub-two/article-3/'
'https://example.com/cost-center/sub-1/sub-two/sub-three/article-5'
"https://example.com/cost-center/sub-one/sub-three/article-4"
"https://example.com/cost-center/sub-1/sub-two/sub-three/article-5/"
这些将被替换如下:
https://example.com/cost-center/test/article-3/
https://example.com/cost-center/test/article-4
https://example.com/cost-center/test/article-5/
'https://example.com/cost-center/test/article-3/'
'https://example.com/cost-center/test/article-5'
"https://example.com/cost-center/test/article-4"
"https://example.com/cost-center/test/article-5/"
现在我们假设 url 在 /cost-center/
; 之后有 至少一个
和最多三个部分
例如
https://example.com/cost-center/sub-1/sub-two/sub-three/article-5/
所以基本上我想替换其中的一些部分,同时保留最后一部分。
我尝试使用许多正则表达式,例如:
preg_replace('~https://example.com/cost-center/[^/]+/([^/]+)~', 'https://example.com/cost-center/test/$1', $url);
preg_replace('/(["\']?)(https:\/\/[^\/]+\/)([^\/]+)(\/[^"\s]*)?/', '$1$2test$4$1', $url);
我也尝试过使用
explode
拆分 url 并手动逐段解析它,但结果非常复杂且丑陋。
ChatGPT
也没有什么好结果。
根据您对任务的描述和示例数据,URL 是否/如何用引号括起来实际上并不重要。您只需匹配 URL 的前导部分即可验证它是否是 URL,然后隔离不需要的子字符串并替换它。
请注意,我的替换值只是字符串
test
并且没有对捕获组的引用。这是因为 \K
将忘记/释放到该点匹配的所有字符,并且 (?= ... )
是一个前瞻,意味着它不会消耗任何匹配的字符。
至于隔离要替换的模式部分,我使用包含正斜杠和空格的否定字符类,然后是文字正斜杠。该子模式可能会重复一次或多次(因为
+
量词)。
代码:(演示)
echo preg_replace('#https://[^/]+/cost-center/\K([^/\s]+/)+(?=article)#', 'test/', $text);
我尝试了以下方法: 正则表达式捕获 3 组:
/cost-center/
/cost-center/
和网址最后一部分之间的所有内容$pattern = '/(https:\/\/example.com\/cost-center\/)(.*?)([^\/]+\/?$)/';
$replacement = '$1test/$3';
$result = preg_replace($pattern, $replacement, $url);
在替换字符串中,保留第一组和第三组
($1 and $3)
,并用 test/ 替换第二组。它将用 /const-center/
替换
test/
和网址最后部分之间的文本
编辑:我修改了正则表达式,以包含引号和属性名称,以应对 URL 位于 HTML 属性(例如 href)内的情况
$pattern = '/(href=["\']https:\/\/example.com\/cost-center\/)(.*?)([^\/]+\/?["\'])/';