Last active
March 30, 2016 14:29
-
-
Save ststeiger/8380132a80f1f5eddb7f0846d5e38f58 to your computer and use it in GitHub Desktop.
How to correctly reverse a string (GraphemeClusters)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "unicode" | |
| "regexp" | |
| ) | |
| func main() { | |
| str := "\u0308" + "a\u0308" + "o\u0308" + "u\u0308" | |
| println("u\u0308" + "o\u0308" + "a\u0308" + "\u0308" == ReverseGrapheme(str)) | |
| println("u\u0308" + "o\u0308" + "a\u0308" + "\u0308" == ReverseGrapheme2(str)) | |
| } | |
| func ReverseGrapheme(str string) string { | |
| buf := []rune("") | |
| checked := false | |
| index := 0 | |
| ret := "" | |
| for _, c := range str { | |
| if !unicode.Is(unicode.M, c) { | |
| if len(buf) > 0 { | |
| ret = string(buf) + ret | |
| } | |
| buf = buf[:0] | |
| buf = append(buf, c) | |
| if checked == false { | |
| checked = true | |
| } | |
| } else if checked == false { | |
| ret = string(append([]rune(""), c)) + ret | |
| } else { | |
| buf = append(buf, c) | |
| } | |
| index += 1 | |
| } | |
| return string(buf) + ret | |
| } | |
| func ReverseGrapheme2(str string) string { | |
| re := regexp.MustCompile("\\PM\\pM*|.") | |
| slice := re.FindAllString(str, -1) | |
| length := len(slice) | |
| ret := "" | |
| for i := 0; i < length; i += 1 { | |
| ret += slice[length-1-i] | |
| } | |
| return ret | |
| } | |
| ////////////////// | |
| // The below functions are, to use the precise technical term, WRONG | |
| ////////////////// | |
| func ReverseSimpleButIncorrect(s string) string { | |
| runes := []rune(s) | |
| for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 { | |
| runes[i], runes[j] = runes[j], runes[i] | |
| } | |
| return string(runes) | |
| } | |
| func ReverseFastButIncorrect(s string) string { | |
| size := len(s) | |
| buf := make([]byte, size) | |
| for start := 0; start < size; { | |
| r, n := utf8.DecodeRuneInString(s[start:]) | |
| start += n | |
| utf8.EncodeRune(buf[size-start:], r) | |
| } | |
| return string(buf) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment