C#でファイルパスの正規化を行おうと思ったのですが、絶対パスならSystem.IO.Path.GetFullName()で可能ですが相対パスについては上手く動作するコードがなかったので、こちらで作ったコードを公開しようと思います。

一応テスト済みですが、もし不具合があったら教えて頂けると助かります。


<br />
// using System.Collections.Generic;<br />
// using System.IO;<br />
// using System.Linq;</p>
<p>public static string Regulate(string path)<br />
{<br />
    if (path == null)<br />
        throw new ArgumentNullException(nameof(path));</p>
<p>    var root = Path.IsPathRooted(path);<br />
    var net = path.StartsWith(@&quot;\\&quot;);</p>
<p>    path = path.Trim(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);<br />
    var spath = new LinkedList&lt;string&gt;(path.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)<br />
        .Where(s =&gt; s != &quot;.&quot; &amp;&amp; s != string.Empty));<br />
    var node = spath.First;</p>
<p>    while (node != null)<br />
    {<br />
        if (node.Value == &quot;..&quot;)<br />
        {<br />
            var prev = node.Previous;<br />
            if (prev != null &amp;&amp; prev.Value != &quot;..&quot;)<br />
            {<br />
                spath.Remove(prev);<br />
                var rm = node;<br />
                node = node.Next;<br />
                spath.Remove(rm);<br />
            }<br />
            else<br />
            {<br />
                node = node.Next;<br />
            }<br />
        }<br />
        else<br />
        {<br />
            node = node.Next;<br />
        }<br />
    }</p>
<p>    if (root &amp;&amp; (spath.Count == 0 || spath.First.Value == &quot;..&quot;))<br />
        throw new ArgumentException(&quot;ルートパスを超える..が含まれています。&quot;);</p>
<p>    path = Path.Combine(spath.ToArray());<br />
    if (net)<br />
        path = @&quot;\\&quot; + path;<br />
    else if (root &amp;&amp; !Path.IsPathRooted(path))<br />
        path = Path.DirectorySeparatorChar + path;</p>
<p>    return path;<br />
}<br />