在 Go 中,字串被視為位元組切片而不是字元序列。這使得執行字元級操作(如反轉字串)變得具有挑戰性。
讓我們考慮以下場景:我們有幾個長度不同的隨機字元字串(100、 200、300、400 和 500)。我們想要反轉每個字串的字元。
嘗試將字元直接指派給字串中的不同索引會導致錯誤,因為 Go 不允許直接字元級字串賦值。
Andrew Sellers 在他的要點中提供了一種創新方法,用於處理結合變音標記 (CDM) 和其他複雜 Unicode 字元的 Unicode。
他引入了一種偵測和保留 CDM 順序的技術,CDM 是複雜 Unicode 區塊的一部分,會影響字串中的字元組合。
解決方案涉及迭代字串以相反的順序並使用範圍表識別 CDM。 CDM 被存儲,然後與常規字元組合,然後將其添加到反向數組中。
對於表情符號和修飾符等字符,該方法需要特別考慮以保留元素的順序以及組合字形的正確表示。
以下是基於 Andrew Sellers 方法的程式碼片段:
<code class="go">package main import ( "fmt" "os" "runtime" "unicode" ) func main() { var stringsToReverse = []string{"Hello, World", "??⃠?", "???????⚖️", "aͤoͧiͤ š́ž́ʟ́", "H̙̖ell͔o̙̟͚͎̗̹̬ ̯W̖͝ǫ̬̞̜rḷ̦̣̪d̰̲̗͈"} for _, s := range stringsToReverse { fmt.Printf("Reverse '%s' => '%s'\n", s, ReverseString(s)) } fmt.Printf("Memory usage: %d bytes\n", runtime.MemStats.Alloc) os.Exit(0) } // ReverseString reverses the characters in a string, handling Unicode combining diacritical marks func ReverseString(s string) string { sv := []rune(s) cv := make([]rune, 0) rv := make([]rune, 0) for ix := len(sv) - 1; ix >= 0; ix-- { r := sv[ix] if unicode.In(r, combining) { cv = append(cv, r) fmt.Printf("Detect combining diacritical mark ' %c'\n", r) } else { rrv := make([]rune, 0, len(cv)+1) rrv = append(rrv, r) rrv = append(rrv, cv...) fmt.Printf("regular mark '%c' (with '%d' combining diacritical marks '%s') => '%s'\n", r, len(cv), string(cv), string(rrv)) rv = append(rv, rrv...) cv = make([]rune, 0) } } return string(rv) }</code>
以上是如何在 Go 中反轉字串,處理 Unicode 組合變音符號?的詳細內容。更多資訊請關注PHP中文網其他相關文章!