Vb.net 使用未知父引用规范化路径 问题陈述
我当前的项目需要处理许多unix风格的路径,最重要的是连接路径和规范化路径 通过规范化,我的意思是删除对当前目录(Vb.net 使用未知父引用规范化路径 问题陈述,vb.net,path,normalization,Vb.net,Path,Normalization,我当前的项目需要处理许多unix风格的路径,最重要的是连接路径和规范化路径 通过规范化,我的意思是删除对当前目录()的所有引用、对父目录(。)的引用和冗余的前斜杠(/),同时保留原始路径的“含义” 例如:路径/foo/bar和/foo//bar和/foo/baz//bar都指向同一目录。然而,进行简单的字符串比较显然表明它们是不同的路径。这就是为什么我试图规范化路径,以便它们都被同等对待 这样做的代码实际上并不难写。你可以在问题的底部找到我的代码。但还有一个问题,我有麻烦 目前,用户可以输入如下
)的所有引用、对父目录(。
)的引用和冗余的前斜杠(/
),同时保留原始路径的“含义”
例如:路径/foo/bar
和/foo//bar
和/foo/baz//bar
都指向同一目录。然而,进行简单的字符串比较显然表明它们是不同的路径。这就是为什么我试图规范化路径,以便它们都被同等对待
这样做的代码实际上并不难写。你可以在问题的底部找到我的代码。但还有一个问题,我有麻烦
目前,用户可以输入如下所示的路径:
input: /../../../foo/bar
normalized: /foo/bar
因为这是一个绝对路径,所以它正确解析为根目录(/
)中的foo/bar
然而,当输入是一个相对路径时,我不可能回溯所需的步骤数量,因为我不知道父目录的名称
input: ../../../foo/bar
normalized: foo/bar
假设完整路径是/a/b/c/d/../../../../../foo/bar
,在这种情况下,算法生成:
input: /a/b/c/d/../../../foo/bar
normalized: /a/foo/bar
无论出于何种原因,当路径被拆分为/a/b/c/d
和。/../../../foo/bar
时,就会出现问题
input: /a/b/c/d/
input: ../../../foo/bar
normalized: /a/b/c/d
normalized: foo/bar
joined: /a/b/c/d/foo/bar
如您所见,当规范化输出值重新连接在一起时,路径已失去其原始含义。如果我没有删除前导父引用,就不会发生这种情况
所以我想我有3个选项,在相对路径未知父引用的情况下:
Public MustInherit类UnixPath
私人分新
端接头
'''
''获取指定的路径是否为绝对路径。
'''
公共共享函数IsAbsolute(路径为字符串)为布尔值
返回path.StartsWith(UnixPath.Separator、StringComparison.InvariantCulture)
端函数
'''
''规范化字符串路径,考虑'..'和'.'部分。
'''
公共共享函数规范化(路径为字符串)为字符串
如果String.IsNullOrEmpty(路径),则
返回字符串。空
如果结束
Dim oldPath=path.Split(New Char(){UnixPath.Separator},StringSplitOptions.RemoveEmptyEntries)
将新路径调整为新堆栈(字符串的)
Dim skipCount As Integer=0
对于i=oldPath.GetUpperBound(0)到oldPath.GetLowerBound(0)步骤-1
如果String.Equals(oldPath(i)、UnixPath.CurrentDirectory、StringComparison.InvariantCulture),则
继续
ElseIf String.Equals(oldPath(i)、UnixPath.ParentDirectory、StringComparison.InvariantCulture)然后
skipCount+=1
如果skipCount>0,则
skipCount-=1
其他的
newPath.Push(旧路径(i))
如果结束
下一个
如果使用UnixPath.IsAbsolute(路径),则
返回UnixPath.Join(UnixPath.Separator,UnixPath.Join(newPath.ToArray))
其他的
对于i=1,进行skipCount
Push(UnixPath.ParentDirectory)
下一个
返回UnixPath.Join(newPath.ToArray)
如果结束
端函数
'''
''组合了一个字符串路径数组。
'''
公共共享函数联接(参数数组路径为String())为String
Dim builder作为新的StringBuilder
Dim count=路径。GetUpperBound(0)
对于i=path.GetLowerBound(0)进行计数
如果String.IsNullOrEmpty(路径(i))那么
继续
如果结束
Append(路径(i).TrimEnd(UnixPath.Separator))
如果我=计数,那么
退出
如果结束
Append(UnixPath.Separator)
下一个
Return builder.ToString
端函数
公共共享只读属性CurrentDirectory作为字符串
得到
返回”
结束
端属性
公共共享只读属性ParentDirectory作为字符串
得到
返回“.”
结束
端属性
公共共享只读属性分隔符作为字符
得到
返回“/”c
结束
端属性
末级
删除不会保留原始路径的意义。
,只能删除重复的
和/
。不过,你想做什么还不清楚。可能你真的不需要这样“规范化”你的路径
无论如何,这里有一个想法:
Dim inputPath As String = "/../../../foo/bar"
Dim outputPath As String = inputPath.Replace(".", "").Replace("..", "")
Dim outputPathLength As Integer
Do
outputPathLength = outputPath.Length
outputPath = outputPath.Replace("//", "/")
Loop Until outputPathLength = outputPath.Length
为了获得更好的实现(这也可以解释您的案例2,以及更多),您可能应该使用正则表达式
编辑:有些人可能会认为这是黑客行为,但这里有另一种选择:
Dim inputPath As String = "../../../foo/bar"
Dim outPath As String = IO.Path.GetFullPath(IO.Path.Combine("C:\", inputPath))
Dim newPath As String = outPath.Substring(outPath.IndexOf("\") + 1).Replace("\", "/")
If inputPath.StartsWith("/") Then newPath = "/" & newPath
MsgBox(newPath)
它使用文件系统规范化路径,并转换回unix样式。适用于上述所有测试用例。顺便说一句,如果无法确定前导父引用的名称,我倾向于将它们放回原位。赞成还是反对?有人吗?你好!我在我的问题陈述中添加了一个例子,以更好地解释我正在尝试做什么。我附加的代码非常完整,尽管我希望看到一个使用正则表达式的工作替代方案
Dim inputPath As String = "../../../foo/bar"
Dim outPath As String = IO.Path.GetFullPath(IO.Path.Combine("C:\", inputPath))
Dim newPath As String = outPath.Substring(outPath.IndexOf("\") + 1).Replace("\", "/")
If inputPath.StartsWith("/") Then newPath = "/" & newPath
MsgBox(newPath)