46 lines
1.4 KiB
Go
46 lines
1.4 KiB
Go
package hw02_unpack_string //nolint:golint,stylecheck
|
|
|
|
import (
|
|
"errors"
|
|
"strconv"
|
|
"strings"
|
|
"unicode"
|
|
)
|
|
|
|
var ErrInvalidString = errors.New("invalid string")
|
|
|
|
const slash = '\\'
|
|
|
|
func Unpack(str string) (string, error) {
|
|
var b strings.Builder
|
|
temp := []rune(str)
|
|
for i := 0; i < len(temp); i++ {
|
|
switch {
|
|
// Ловим паттерн [\][letter][digit]
|
|
case temp[i] == slash && i < len(temp)-2 && unicode.IsLetter(temp[i+1]) && unicode.IsDigit(temp[i+2]):
|
|
c, _ := strconv.Atoi(string(temp[i+2]))
|
|
b.WriteString(strings.Repeat(string(slash)+string(temp[i+1]), c))
|
|
i += 2
|
|
// Ловим паттерн [\][digit или \][digit]
|
|
case temp[i] == slash && i < len(temp)-2 && (unicode.IsDigit(temp[i+1]) || temp[i+1] == slash) && unicode.IsDigit(temp[i+2]):
|
|
c, _ := strconv.Atoi(string(temp[i+2]))
|
|
b.WriteString(strings.Repeat(string(temp[i+1]), c))
|
|
i += 2
|
|
// Ловим паттерн [\][digit или \]
|
|
case temp[i] == slash && i < len(temp)-1 && (unicode.IsDigit(temp[i+1]) || temp[i+1] == slash):
|
|
b.WriteRune(temp[i+1])
|
|
i++
|
|
case unicode.IsLetter(temp[i]) && i < len(temp)-1 && unicode.IsDigit(temp[i+1]):
|
|
c, _ := strconv.Atoi(string(temp[i+1]))
|
|
b.WriteString(strings.Repeat(string(temp[i]), c))
|
|
i++
|
|
// Ловим паттерн [letter]...
|
|
case unicode.IsLetter(temp[i]):
|
|
b.WriteRune(temp[i])
|
|
default:
|
|
return "", ErrInvalidString
|
|
}
|
|
}
|
|
return b.String(), nil
|
|
}
|