Решение на Нормализация на пътища от Александър Димитров

Обратно към всички решения

Към профила на Александър Димитров

Резултати

  • 10 точки от тестове
  • 0 бонус точки
  • 10 точки общо
  • 8 успешни тест(а)
  • 0 неуспешни тест(а)

Код

package main
import "regexp"
func parseValidDir(src string) string {
regexUpDir := regexp.MustCompile("[^/]+/\\.\\.(/|$)")
path := src
for {
stringList := regexUpDir.Split(path, 2)
if len(stringList) == 2 {
path = stringList[0] + stringList[1]
} else { //if the stringList has only 1 element, there is nothing left to parse
return path
}
}
}
func parsePath(path string) string {
//add / at the beginning and end to make sure we have it
parsedPath := "/" + path + "/"
regexExtraSlashes := regexp.MustCompile("/(/+)")
regexExtraSingleDots := regexp.MustCompile("(^\\./|/\\./|/\\.$)")
parsedPath = regexExtraSingleDots.ReplaceAllString(parsedPath, "/")
parsedPath = regexExtraSlashes.ReplaceAllString(parsedPath, "/")
parsedPath = parseValidDir(parsedPath) //parse all valid substrings that go into a dir and then leave it
regexExtraDoubleDots := regexp.MustCompile("(^\\.\\./|/\\.\\./|/\\.\\.$)")
parsedPath = regexExtraDoubleDots.ReplaceAllString(parsedPath, "/")
parsedPath = regexExtraSlashes.ReplaceAllString(parsedPath, "/")
return parsedPath
}

Лог от изпълнението

PASS
ok  	_/tmp/d20131015-29033-3yod2t	0.012s
PASS
ok  	_/tmp/d20131015-29033-3yod2t	0.011s
PASS
ok  	_/tmp/d20131015-29033-3yod2t	0.011s
PASS
ok  	_/tmp/d20131015-29033-3yod2t	0.011s
PASS
ok  	_/tmp/d20131015-29033-3yod2t	0.011s
PASS
ok  	_/tmp/d20131015-29033-3yod2t	0.011s
PASS
ok  	_/tmp/d20131015-29033-3yod2t	0.011s
PASS
ok  	_/tmp/d20131015-29033-3yod2t	0.011s

История (2 версии и 2 коментара)

Александър обнови решението на 12.10.2013 10:45 (преди над 4 години)

+package main
+
+import "regexp"
+
+func parseFirstDir(src string) string {
+ regexUpDir := regexp.MustCompile("[^/]+/\\.\\.(/|$)")
+ stringList := regexUpDir.Split(src, 2)
+ if len(stringList) == 2 {
+ return stringList[0] + stringList[1]
+ } else {
+ return stringList[0]
+ }
+}
+
+func parsePath(path string) string {
+ //add / at the beginning to make sure we have it
+ oldPath := "/" + path
+
+ regexExtraSlashes := regexp.MustCompile("/(/+)")
+ newPath := regexExtraSlashes.ReplaceAllString(oldPath, "/")
+
+ //parse all valid substrings that go into a dir and then leave it
+ for {
+ oldPath = newPath
+ newPath = parseFirstDir(oldPath)
+ if oldPath == newPath {
+ break
+ }
+ }
+
+ //parse all extra single dots and double dots
+ regexExtraDots := regexp.MustCompile("(^\\./|/\\./|/\\.$)|(^\\.\\./|/\\.\\./|/\\.\\.$)")
+ newPath = regexExtraDots.ReplaceAllString(newPath, "/")
+ newPath = regexExtraSlashes.ReplaceAllString(newPath, "/")
+
+ return newPath
+}

Това наименоване newPath и oldPath ми е доста странно. Дори все още не съм сигурен кое е старото на oldPath.

Иначе хакът да заместваш неща като ../ или ./ с /, след което да премахваш дублиращите се наклонени черти е доста любопитен.

Александър обнови решението на 14.10.2013 11:56 (преди над 4 години)

package main
import "regexp"
-func parseFirstDir(src string) string {
+func parseValidDir(src string) string {
regexUpDir := regexp.MustCompile("[^/]+/\\.\\.(/|$)")
- stringList := regexUpDir.Split(src, 2)
- if len(stringList) == 2 {
- return stringList[0] + stringList[1]
- } else {
- return stringList[0]
+ path := src
+
+ for {
+ stringList := regexUpDir.Split(path, 2)
+
+ if len(stringList) == 2 {
+ path = stringList[0] + stringList[1]
+ } else { //if the stringList has only 1 element, there is nothing left to parse
+ return path
+ }
}
}
func parsePath(path string) string {
- //add / at the beginning to make sure we have it
- oldPath := "/" + path
+ //add / at the beginning and end to make sure we have it
+ parsedPath := "/" + path + "/"
regexExtraSlashes := regexp.MustCompile("/(/+)")
- newPath := regexExtraSlashes.ReplaceAllString(oldPath, "/")
+ regexExtraSingleDots := regexp.MustCompile("(^\\./|/\\./|/\\.$)")
- //parse all valid substrings that go into a dir and then leave it
- for {
- oldPath = newPath
- newPath = parseFirstDir(oldPath)
- if oldPath == newPath {
- break
- }
- }
+ parsedPath = regexExtraSingleDots.ReplaceAllString(parsedPath, "/")
+ parsedPath = regexExtraSlashes.ReplaceAllString(parsedPath, "/")
- //parse all extra single dots and double dots
- regexExtraDots := regexp.MustCompile("(^\\./|/\\./|/\\.$)|(^\\.\\./|/\\.\\./|/\\.\\.$)")
- newPath = regexExtraDots.ReplaceAllString(newPath, "/")
- newPath = regexExtraSlashes.ReplaceAllString(newPath, "/")
+ parsedPath = parseValidDir(parsedPath) //parse all valid substrings that go into a dir and then leave it
- return newPath
+ regexExtraDoubleDots := regexp.MustCompile("(^\\.\\./|/\\.\\./|/\\.\\.$)")
+ parsedPath = regexExtraDoubleDots.ReplaceAllString(parsedPath, "/")
+ parsedPath = regexExtraSlashes.ReplaceAllString(parsedPath, "/")
+
+ return parsedPath
}

Извинявам се за недоразумението, при имената на променливите. Мисля, че сега се разбира по-адекватно кое, какво е.

По отношение на хакът за заместване на ../ в началото, /../ посредата, /.. в края и т.н. за единични точки, го промених малко. Ако това не е добър начин да се изчисти пътеката от боклуци, които операционната система не би позволила пъвроначално, ще мисля върху по-добър начин това да стане.