2016-04-29 174 views
4

我正在計算go中的「characters」。也就是說,如果一個字符串包含一個可打印的「字形」或「組合字符」(或某人通常認爲的字符),我希望它計爲1.例如,字符串「Hello,世界」應該數11,因爲有11個字符,並且人會看這個並且說有11個字形。在golang字符串中計數字符

utf8.RuneCountInString()在大多數情況下效果很好,包括ascii,口音,亞洲字符,甚至表情符號。但是,據我所知,符文對應於代碼點,而不是字符。當我嘗試使用它的工作原理基本表情符號,但是當我使用具有不同膚色表情符號,我拿錯數:https://play.golang.org/p/aFIGsB6MsO

從我讀herehere以下應該工作,但我還是不似乎得到正確的結果(它過計數):

func CountCharactersInString(str string) int { 
    var ia norm.Iter 
    ia.InitString(norm.NFC, str) 
    nc := 0 
    for !ia.Done() { 
     nc = nc + 1 
     ia.Next() 
    } 
    return nc 
} 

這不起作用或者:

func GraphemeCountInString(str string) int { 
    re := regexp.MustCompile("\\PM\\pM*|.") 
    return len(re.FindAllString(str, -1)) 
} 

我要尋找的目標C類似於此:

+ (NSInteger)countCharactersInString:(NSString *) string { 
    // --- Calculate the number of characters enterd by user and update character count label 
    NSInteger count = 0; 
    NSUInteger index = 0; 
    while (index < string.length) { 
     NSRange range = [string rangeOfComposedCharacterSequenceAtIndex:index]; 
     count++; 
     index += range.length; 
    } 
    return count; 
} 
+0

您正在尋找[從UAX#29 「字形簇邊界」 算法]中的實現(http://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries)。 –

+0

我認爲是對的。我嘗試了從這個答案http://stackoverflow.com/a/26728555/547291計算字形的兩個實現,但我遇到了同樣的麻煩,但也許字形羣邊界計數更多我想要的? –

+0

這個問題的答案將「字形集羣」與「字符規範化」混爲一談(都有嚴重錯誤)。 –

回答

2

參考API文檔的例子。 https://golang.org/pkg/unicode/utf8/#example_DecodeLastRuneInString

package main 

import (
    "fmt" 
    "unicode/utf8" 
) 

func main() { 
    str := "Hello, 世界" 
    count := 0 
    for len(str) > 0 { 
     r, size := utf8.DecodeLastRuneInString(str) 
     count++ 
     fmt.Printf("%c %v\n", r, size) 

     str = str[:len(str)-size] 
    } 
    fmt.Println("count:",count) 
} 
+1

這個數*符文*,而不是*字形*:'str:=「」'計數2而不是1。 –

+0

什麼是「AX」,爲什麼它應該是1? –

+1

這是'U + 1F1E6 U + 1F1FD',它應該是奧蘭羣島的旗幟。任何其他區域性指標符號都會有相同的結果(也許''在您的系統上呈現得更好?)。 –

1

你試過strings.Count

package main 

import (
    "fmt" 
    "strings" 
) 

func main() { 
    fmt.Println(strings.Count("Hello, 世界", "")) // Returns 2 
} 
+0

在「Hello,世界」的例子中,我希望它數11,因爲有11個字符,而不是2.我將編輯我的問題來澄清。 –