Решение на Markdown от Георги Пеев

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

Към профила на Георги Пеев

Резултати

  • 6 точки от тестове
  • 0 бонус точки
  • 6 точки общо
  • 4 успешни тест(а)
  • 3 неуспешни тест(а)

Код

package main
import (
"regexp"
"strconv"
"strings"
)
type MarkdownParser struct {
data string
}
func NewMarkdownParser(text string) *MarkdownParser {
result := new(MarkdownParser)
result.data = text
return result
}
func (mp *MarkdownParser) Headers() []string {
h1re := regexp.MustCompile(`(?m)(^#\s.+(\s?)#*$)|(^(.+)\n(=+)$)`)
trimRe := regexp.MustCompile(`(?m)^# |( #+$)|\n(=+)$`)
result := h1re.FindAllString(mp.data, -1)
for key, val := range result {
result[key] = strings.Trim(trimRe.ReplaceAllString(val, ""), "\n")
}
return result
}
func (mp *MarkdownParser) SubHeadersOf(header string) []string {
str := strings.SplitN(mp.data, header, 2)[1]
h1re := regexp.MustCompile(`(?m)(^#\s.+(\s?)#*$)|(^(.+)\n(=+)$)`)
str = h1re.Split(str, -1)[0]
h2re := regexp.MustCompile(`(?m)(^##\s.+(\s?)#*$)|(^(.+)\n(-+)$)`)
trimRe := regexp.MustCompile(`(?m)^## |( #+$\n?)|\n(-+)$\n?|\n`)
result := h2re.FindAllString(str, -1)
for key, val := range result {
result[key] = trimRe.ReplaceAllString(val, "")
}
return result
}
func (mp *MarkdownParser) Names() []string {
sentRe := regexp.MustCompile(`[A-ZА-Я][^\.\?!]*[\.\?!]`)
nameRe := regexp.MustCompile(`(?m)\s(([A-ZА-Я][a-zа-я]*)[\s-]+)+([A-ZА-Я][a-zа-я]*)`)
sentences := sentRe.FindAllString(mp.data, -1)
var result []string
for _, v := range sentences {
for _, item := range nameRe.FindAllString(v, -1) {
result = append(result, strings.Trim(item, " "))
}
}
return result
}
func (mp *MarkdownParser) PhoneNumbers() []string {
phoneRe := regexp.MustCompile(`(?m)\s(\+?)(\s*\-?\s*(\(?)(\d+)(\)?))+(\s|$)`)
result := phoneRe.FindAllString(mp.data, -1)
for k, v := range result {
result[k] = strings.Trim(strings.Trim(v, " "), "\n")
}
return result
}
func (mp *MarkdownParser) Links() []string {
nameLinkRe := regexp.MustCompile(`\[.+\]\(.+\)`)
linkRe := regexp.MustCompile(`\(.+\)`)
result := nameLinkRe.FindAllString(mp.data, -1)
for k, v := range result {
result[k] = strings.Trim(strings.Trim(linkRe.FindString(v), ")"), "(")
}
return result
}
func (mp *MarkdownParser) Emails() []string {
emailRe := regexp.MustCompile(`(?m)(\s|^)([\w\d][\w\._+-]+)@([\da-zA-Z\.-]+)\.([a-zA-Z]{2,6})`)
result := emailRe.FindAllString(mp.data, -1)
for k, v := range result {
result[k] = strings.Trim(strings.Trim(v, " "), "\n")
}
return result
}
func (mp *MarkdownParser) GenerateTableOfContents() string {
var result string
h1s := mp.Headers()
for k, v := range h1s {
result += strconv.Itoa(k+1) + ". "
result += v + "\n"
h2s := mp.SubHeadersOf(v)
for k1, v1 := range h2s {
result += strconv.Itoa(k+1) + "." + strconv.Itoa(k1+1) + " "
result += v1 + "\n"
h3s := mp.SubHgrs(v1, 3)
for k2, v2 := range h3s {
result += strconv.Itoa(k+1) + "." + strconv.Itoa(k1+1) + "." + strconv.Itoa(k2+1) + " "
result += v2 + "\n"
h4s := mp.SubHgrs(v2, 4)
for k3, v3 := range h4s {
result += strconv.Itoa(k+1) + "." + strconv.Itoa(k1+1) + "." + strconv.Itoa(k2+1) + "." + strconv.Itoa(k3+1) + " "
result += v3 + "\n"
h5s := mp.SubHgrs(v3, 5)
for k4, v4 := range h5s {
result += strconv.Itoa(k+1) + "." + strconv.Itoa(k1+1) + "." + strconv.Itoa(k2+1) + "." + strconv.Itoa(k3+1) + "." + strconv.Itoa(k4+1) + " "
result += v4 + "\n"
h6s := mp.SubHgrs(v4, 6)
for k5, v5 := range h6s {
result += strconv.Itoa(k+1) + "." + strconv.Itoa(k1+1) + "." + strconv.Itoa(k2+1) + "." + strconv.Itoa(k3+1) + "." + strconv.Itoa(k4+1) + "." + strconv.Itoa(k5+1) + " "
result += v5 + "\n"
}
}
}
}
}
}
return result
}
func (mp *MarkdownParser) SubHgrs(header string, n int) []string {
h2re := regexp.MustCompile(`(?m)(^##\s.+(\s?)#*$)|(^(.+)\n(-+)$)`)
h3re := regexp.MustCompile(`(?m)^###\s.+(\s#*)?$`)
h4re := regexp.MustCompile(`(?m)^#{4}\s.+(\s?)#*$`)
h5re := regexp.MustCompile(`(?m)^#{5}\s.+(\s?)#*$`)
h6re := regexp.MustCompile(`(?m)^#{6}\s.+(\s?)#*$`)
trimRe := regexp.MustCompile(`(?m)^#+ |( #+$\n?)`)
var result []string
str := strings.SplitN(mp.data, header, 2)[1]
switch {
case n == 3:
str = h2re.Split(str, -1)[0]
result = h3re.FindAllString(str, -1)
for key, val := range result {
result[key] = strings.Trim(trimRe.ReplaceAllString(val, ""), "\n")
}
case n == 4:
str = h3re.Split(str, -1)[0]
result = h4re.FindAllString(str, -1)
for key, val := range result {
result[key] = strings.Trim(trimRe.ReplaceAllString(val, ""), "\n")
}
case n == 5:
str = h4re.Split(str, -1)[0]
result = h5re.FindAllString(str, -1)
for key, val := range result {
result[key] = strings.Trim(trimRe.ReplaceAllString(val, ""), "\n")
}
case n == 6:
str = h5re.Split(str, -1)[0]
result = h6re.FindAllString(str, -1)
for key, val := range result {
result[key] = strings.Trim(trimRe.ReplaceAllString(val, ""), "\n")
}
}
return result
}

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

PASS
ok  	_/tmp/d20140106-32701-7hlpwa	0.012s
PASS
ok  	_/tmp/d20140106-32701-7hlpwa	0.012s
PASS
ok  	_/tmp/d20140106-32701-7hlpwa	0.013s
--- FAIL: TestPhoneNumbers (0.00 seconds)
	solution_test.go:86: Not equal:
		  []string{"0889123456", "0 (889) 123"}
		  []string{"0889123456", "0 (889) 123", "456", "+45-(31)"}
FAIL
exit status 1
FAIL	_/tmp/d20140106-32701-7hlpwa	0.012s
--- FAIL: TestLinks (0.00 seconds)
	solution_test.go:98: Not equal:
		  []string(nil)
		  []string{"http://somelink.com:230", "https://www.google.bg/search?q=4531&ie=utf-8&oe=utf-8&rls=org.mozilla:en-US:official&client=%20firefox-a&gws_rd=asd&ei=some#somefragment"}
FAIL
exit status 1
FAIL	_/tmp/d20140106-32701-7hlpwa	0.012s
--- FAIL: TestEmails (0.00 seconds)
	solution_test.go:107: Not equal:
		  []string{"validMail12@foobar.com", "_invalidmail@google.com", "toolongmailhereaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@gmail.com", "12mail@gmail.com"}
		  []string{"validMail12@foobar.com", "12mail@gmail.com"}
FAIL
exit status 1
FAIL	_/tmp/d20140106-32701-7hlpwa	0.013s
PASS
ok  	_/tmp/d20140106-32701-7hlpwa	0.015s

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

Георги обнови решението на 02.12.2013 22:59 (преди над 4 години)

+package main
+
+import (
+ "regexp"
+ "strconv"
+ "strings"
+)
+
+type MarkdownParser struct {
+ data string
+}
+
+func NewMarkdownParser(text string) *MarkdownParser {
+ result := new(MarkdownParser)
+ result.data = text
+ return result
+}
+
+func (mp *MarkdownParser) Headers() []string {
+ h1re := regexp.MustCompile(`(?m)(^#\s.+(\s?)#*$)|(^(.+)\n(=+)$)`)
+ trimRe := regexp.MustCompile(`(?m)^# |( #+$)|\n(=+)$`)
+ result := h1re.FindAllString(mp.data, -1)
+ for key, val := range result {
+ result[key] = strings.Trim(trimRe.ReplaceAllString(val, ""), "\n")
+ }
+ return result
+}
+
+func (mp *MarkdownParser) SubHeadersOf(header string) []string {
+ str := strings.SplitN(mp.data, header, 2)[1]
+ h1re := regexp.MustCompile(`(?m)(^#\s.+(\s?)#*$)|(^(.+)\n(=+)$)`)
+ str = h1re.Split(str, -1)[0]
+ h2re := regexp.MustCompile(`(?m)(^##\s.+(\s?)#*$)|(^(.+)\n(-+)$)`)
+ trimRe := regexp.MustCompile(`(?m)^## |( #+$\n?)|\n(-+)$\n?|\n`)
+ result := h2re.FindAllString(str, -1)
+ for key, val := range result {
+ result[key] = trimRe.ReplaceAllString(val, "")
+ }
+ return result
+}
+
+func (mp *MarkdownParser) Names() []string {
+ sentRe := regexp.MustCompile(`[A-ZА-Я][^\.\?!]*[\.\?!]`)
+ nameRe := regexp.MustCompile(`(?m)\s(([A-ZА-Я][a-zа-я]*)[\s-]+)+([A-ZА-Я][a-zа-я]*)`)
+ sentences := sentRe.FindAllString(mp.data, -1)
+ var result []string
+ for _, v := range sentences {
+ for _, item := range nameRe.FindAllString(v, -1) {
+ result = append(result, strings.Trim(item, " "))
+ }
+ }
+ return result
+}
+
+func (mp *MarkdownParser) PhoneNumbers() []string {
+ phoneRe := regexp.MustCompile(`(?m)\s(\+?)(\s*\-?\s*(\(?)(\d+)(\)?))+(\s|$)`)
+ result := phoneRe.FindAllString(mp.data, -1)
+ for k, v := range result {
+ result[k] = strings.Trim(strings.Trim(v, " "), "\n")
+ }
+ return result
+}
+
+func (mp *MarkdownParser) Links() []string {
+ nameLinkRe := regexp.MustCompile(`\[.+\]\(.+\)`)
+ linkRe := regexp.MustCompile(`\(.+\)`)
+ result := nameLinkRe.FindAllString(mp.data, -1)
+ for k, v := range result {
+ result[k] = strings.Trim(strings.Trim(linkRe.FindString(v), ")"), "(")
+ }
+ return result
+}
+
+func (mp *MarkdownParser) Emails() []string {
+ emailRe := regexp.MustCompile(`(?m)(\s|^)([\w\d][\w\._+-]+)@([\da-zA-Z\.-]+)\.([a-zA-Z]{2,6})`)
+ result := emailRe.FindAllString(mp.data, -1)
+ for k, v := range result {
+ result[k] = strings.Trim(strings.Trim(v, " "), "\n")
+ }
+ return result
+}
+
+func (mp *MarkdownParser) GenerateTableOfContents() string {
+ var result string
+ h1s := mp.Headers()
+ for k, v := range h1s {
+ result += strconv.Itoa(k+1) + ". "
+ result += v + "\n"
+ h2s := mp.SubHeadersOf(v)
+ for k1, v1 := range h2s {
+ result += strconv.Itoa(k+1) + "." + strconv.Itoa(k1+1) + " "
+ result += v1 + "\n"
+ h3s := mp.SubHgrs(v1, 3)
+ for k2, v2 := range h3s {
+ result += strconv.Itoa(k+1) + "." + strconv.Itoa(k1+1) + "." + strconv.Itoa(k2+1) + " "
+ result += v2 + "\n"
+ h4s := mp.SubHgrs(v2, 4)
+ for k3, v3 := range h4s {
+ result += strconv.Itoa(k+1) + "." + strconv.Itoa(k1+1) + "." + strconv.Itoa(k2+1) + "." + strconv.Itoa(k3+1) + " "
+ result += v3 + "\n"
+ h5s := mp.SubHgrs(v3, 5)
+ for k4, v4 := range h5s {
+ result += strconv.Itoa(k+1) + "." + strconv.Itoa(k1+1) + "." + strconv.Itoa(k2+1) + "." + strconv.Itoa(k3+1) + "." + strconv.Itoa(k4+1) + " "
+ result += v4 + "\n"
+ h6s := mp.SubHgrs(v4, 6)
+ for k5, v5 := range h6s {
+ result += strconv.Itoa(k+1) + "." + strconv.Itoa(k1+1) + "." + strconv.Itoa(k2+1) + "." + strconv.Itoa(k3+1) + "." + strconv.Itoa(k4+1) + "." + strconv.Itoa(k5+1) + " "
+ result += v5 + "\n"
+ }
+ }
+ }
+ }
+ }
+ }
+ return result
+}
+
+func (mp *MarkdownParser) SubHgrs(header string, n int) []string {
+ h2re := regexp.MustCompile(`(?m)(^##\s.+(\s?)#*$)|(^(.+)\n(-+)$)`)
+ h3re := regexp.MustCompile(`(?m)^###\s.+(\s#*)?$`)
+ h4re := regexp.MustCompile(`(?m)^#{4}\s.+(\s?)#*$`)
+ h5re := regexp.MustCompile(`(?m)^#{5}\s.+(\s?)#*$`)
+ h6re := regexp.MustCompile(`(?m)^#{6}\s.+(\s?)#*$`)
+ trimRe := regexp.MustCompile(`(?m)^#+ |( #+$\n?)`)
+ var result []string
+ str := strings.SplitN(mp.data, header, 2)[1]
+ switch {
+ case n == 3:
+ str = h2re.Split(str, -1)[0]
+ result = h3re.FindAllString(str, -1)
+ for key, val := range result {
+ result[key] = strings.Trim(trimRe.ReplaceAllString(val, ""), "\n")
+ }
+ case n == 4:
+ str = h3re.Split(str, -1)[0]
+ result = h4re.FindAllString(str, -1)
+ for key, val := range result {
+ result[key] = strings.Trim(trimRe.ReplaceAllString(val, ""), "\n")
+ }
+ case n == 5:
+ str = h4re.Split(str, -1)[0]
+ result = h5re.FindAllString(str, -1)
+ for key, val := range result {
+ result[key] = strings.Trim(trimRe.ReplaceAllString(val, ""), "\n")
+ }
+ case n == 6:
+ str = h5re.Split(str, -1)[0]
+ result = h6re.FindAllString(str, -1)
+ for key, val := range result {
+ result[key] = strings.Trim(trimRe.ReplaceAllString(val, ""), "\n")
+ }
+ }
+ return result
+}
  • Това ниво на влагане в GenerateTableOfContents изобщо не ми харесва
  • case-овете в SubHgrs са доста еднакви. Помисли си как би могъл да ги експортнеш в ламбда
  • Някои неща са публични без да има нужда от това. Оставяй публични само тези методи/функции/типове, които сме описали като изискване