如何使用UriBuilder修改Uri路径并保持输入格式完全一致?
解决URL路径替换并严格保留原始格式的问题
需求是将各类URL中的test路径段替换为testcontent,同时严格保留输入的原始格式(包括相对路径、根相对路径、无协议绝对路径、带协议绝对路径的格式,以及查询参数、锚点部分),输入输出示例如下:
Inp: test/something.js?v=1#a Out: testcontent/something.js?v=1#a Inp: /test/something.js?v=1#a Out: /testcontent/something.js?v=1#a Inp: ://example.com/test/something.js?v=1#a Out: ://example.com/testcontent/something.js?v=1#a Inp: https://example.com/test/something.js?v=1#a Out: https://example.com/testcontent/something.js?v=1#a
之前通过Uri类和MakeRelativeUri的方案存在格式丢失问题,原因是Uri类会标准化路径,MakeRelativeUri生成的相对路径可能和原始输入格式不一致,且无法正确处理://example.com/这类无协议的特殊URL。
解决方案:直接基于字符串正则替换
直接对原始URL字符串进行正则匹配替换,既能精准替换目标路径段,又能完全保留原始格式:
static string ReplaceTestPathSegment(string originalUrl) { // 正则匹配路径中的"test/",覆盖四种输入场景: // 1. 相对路径开头的test/ // 2. 根路径开头的/test/ // 3. 绝对路径域名后的/test/ // 只替换路径中的第一个test,不影响查询参数或锚点中的test return Regex.Replace(originalUrl, @"(?<=^|/|://[^/]+/)test(?=/)", "testcontent"); }
测试验证
调用上述方法测试四种输入:
Console.WriteLine(ReplaceTestPathSegment("test/something.js?v=1#a")); // 输出:testcontent/something.js?v=1#a Console.WriteLine(ReplaceTestPathSegment("/test/something.js?v=1#a")); // 输出:/testcontent/something.js?v=1#a Console.WriteLine(ReplaceTestPathSegment("://example.com/test/something.js?v=1#a")); // 输出:://example.com/testcontent/something.js?v=1#a Console.WriteLine(ReplaceTestPathSegment("https://example.com/test/something.js?v=1#a")); // 输出:https://example.com/testcontent/something.js?v=1#a
正则说明
(?<=^|/|://[^/]+/):正向预查,确保test前面是以下情况之一:^:字符串开头(对应相对路径场景)/:路径分隔符(对应根相对路径场景)://[^/]+/:协议://域名/(对应绝对路径场景)
test(?=/):匹配后面跟着路径分隔符的test,确保只替换路径段,不会误匹配查询参数或锚点中的test
补充说明
如果需要替换的是任意位置的test路径段(而非第一个),可以去掉正则中的^限制,调整为:
return Regex.Replace(originalUrl, @"(?<=/|://[^/]+/)test(?=/)", "testcontent");
内容的提问来源于stack exchange,提问作者Luke Vo
相关产品推荐
相关产品推荐

