package main import ( "testing" ) type Type int const ( TypeChild Type = iota TypeChildren TypeAllChildren ) type Node struct { Prev *Node Next *Node Name []rune Type Type } // func extractPath(cur *Node) string { // var path []byte // if cur.Next.Next == nil { // return "/" // } // for ; cur != nil; cur = cur.Next { // path = append(path, cur.Name...) // if cur.Next.Next == nil { // break // } // path = append(path, '/') // } // return string(path) // } func toString(root *Node) string { var content string for root != nil { content += string(root.Name) if root.Type == TypeAllChildren { content += "//" } else { content += "/" } root = root.Next } return content } func xPath(spath string) string { var path []rune = []rune(spath) path = append(path, ' ') root := &Node{} cur := root for i := 0; i < len(spath); i++ { c := path[i] switch c { case '/': if path[i+1] == '/' { cur.Type = TypeAllChildren i++ } else { cur.Type = TypeChild } if len(cur.Name) == 0 { continue } cur.Next = &Node{Prev: cur} cur = cur.Next // case '(': 先拿括号 default: cur.Name = append(cur.Name, c) } } return toString(root) } func TestMain(t *testing.T) { // t.Error(xPath("/a/../../b/../c//.//")) // t.Error(xPath("/a/./b/../../c/")) // t.Error(xPath("/")) t.Error(xPath("/a/./b/../../c/")) // t.Error(xPath("/a//b////c/d//././/..")) }