如何判断一个URL是否为另一个URL的子URL?
如何判断一个URL是否为另一个URL的子URL?
判断核心逻辑:子URL的协议、主机(网络URL场景)必须与父URL完全一致,且路径是父URL路径的直接或间接延伸。以下结合你给出的本地文件URL示例,提供两种可行方法:
方法一:手动字符串匹配(通用场景)
适用于所有平台,无需依赖特定API,步骤如下:
- 步骤1:校验协议一致性:待判断URL的协议必须和父URL完全相同(比如示例中都是
file://)。 - 步骤2:标准化路径格式:给父URL的路径添加结尾斜杠(避免出现
Devices和DevicesX这类前缀误判),同时将所有URL的路径转换为绝对路径。 - 步骤3:前缀匹配校验:检查子URL的路径是否以父URL的标准化路径作为前缀。
结合你的示例验证:
父URL标准化后路径:/Users/me/Library/Developer/CoreSimulator/Devices/
三个待判断URL的路径均满足前缀匹配,因此都是该父URL的子URL。
方法二:利用系统API(Apple平台专属)
如果是iOS/macOS开发,可直接借助Foundation框架的API实现精准判断:
方式1:使用isSubpath(of:)方法(iOS 16+/macOS 13+)
let parentURL = URL(string: "file:///Users/me/Library/Developer/CoreSimulator/Devices")! let testURL1 = URL(string: "file:///Users/me/Library/Developer/CoreSimulator/Devices/folder1/myFile.swift")! let testURL2 = URL(string: "file:///Users/me/Library/Developer/CoreSimulator/Devices/folder1/folder2/myFile.swift")! let testURL3 = URL(string: "file:///Users/me/Library/Developer/CoreSimulator/Devices/myFile.swift")! print(testURL1.isSubpath(of: parentURL)) // 输出true print(testURL2.isSubpath(of: parentURL)) // 输出true print(testURL3.isSubpath(of: parentURL)) // 输出true
方式2:手动对比路径组件(兼容低版本系统)
func isSubURL(child: URL, parent: URL) -> Bool { // 先校验协议一致 guard child.scheme == parent.scheme else { return false } // 过滤空路径组件,取有效路径片段 let childComponents = child.pathComponents.filter { !$0.isEmpty } let parentComponents = parent.pathComponents.filter { !$0.isEmpty } // 子路径组件数量必须不少于父路径 guard childComponents.count >= parentComponents.count else { return false } // 对比前N个组件(N为父路径组件数)是否完全匹配 return childComponents.prefix(parentComponents.count) == parentComponents } // 调用示例 print(isSubURL(child: testURL1, parent: parentURL)) // 输出true
关键注意事项
- 网络URL需额外校验主机:比如
https://example.com/path和https://sub.example.com/path不属于父子关系,因为主机不同。 - 处理相对路径:若URL包含
../这类相对路径,需先调用standardized方法转换为绝对路径再判断。
内容的提问来源于stack exchange,提问作者Hassan Taleb
相关产品推荐
相关产品推荐

