计算golang字符串中的字符
Counting characters in golang string
我正在尝试计算 "characters"。也就是说,如果一个字符串包含一个可打印的 "glyph" 或 "composed character"(或者某些人通常认为的字符),我希望它计数为 1。例如,字符串 "Hello, 世界", 应该数为 11,因为有 11 个字符,人类会看到它并说有 11 个字形。
utf8.RuneCountInString() 在大多数情况下效果很好,包括 ascii、重音符号、亚洲字符甚至表情符号。但是,据我了解,符文对应于代码点,而不是字符。当我尝试使用基本表情符号时它有效,但是当我使用具有不同肤色的表情符号时,我得到错误的计数:https://play.golang.org/p/aFIGsB6MsO
根据我的阅读 and here,以下内容应该有效,但我似乎仍然没有得到正确的结果(多算):
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))
}
我正在 Objective 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;
}
参考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)
}
你试过了吗strings.Count?
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.Count("Hello, 世界", "")) // Returns 2
}
我写了一个包,可以让你这样做:https://github.com/rivo/uniseg. It breaks strings according to the rules specified in Unicode Standard Annex #29 这就是你要找的。以下是您将如何在您的案例中使用它:
package main
import (
"fmt"
"github.com/rivo/uniseg"
)
func main() {
fmt.Println(uniseg.GraphemeClusterCount("Hello, 世界"))
}
这将按您的预期打印 11
。
我认为最简单的方法是这样的:
package main
import "fmt"
func main() {
str := "Hello, 世界"
var counter int
for range str {
counter++
}
fmt.Println(counter)
}
这一个打印 11
直接直接使用 utf8.RuneCountInString()
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
str := "Hello, 世界"
fmt.Println("counts =", utf8.RuneCountInString(str))
}
我正在尝试计算 "characters"。也就是说,如果一个字符串包含一个可打印的 "glyph" 或 "composed character"(或者某些人通常认为的字符),我希望它计数为 1。例如,字符串 "Hello, 世界", 应该数为 11,因为有 11 个字符,人类会看到它并说有 11 个字形。
utf8.RuneCountInString() 在大多数情况下效果很好,包括 ascii、重音符号、亚洲字符甚至表情符号。但是,据我了解,符文对应于代码点,而不是字符。当我尝试使用基本表情符号时它有效,但是当我使用具有不同肤色的表情符号时,我得到错误的计数:https://play.golang.org/p/aFIGsB6MsO
根据我的阅读
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))
}
我正在 Objective 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;
}
参考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)
}
你试过了吗strings.Count?
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.Count("Hello, 世界", "")) // Returns 2
}
我写了一个包,可以让你这样做:https://github.com/rivo/uniseg. It breaks strings according to the rules specified in Unicode Standard Annex #29 这就是你要找的。以下是您将如何在您的案例中使用它:
package main
import (
"fmt"
"github.com/rivo/uniseg"
)
func main() {
fmt.Println(uniseg.GraphemeClusterCount("Hello, 世界"))
}
这将按您的预期打印 11
。
我认为最简单的方法是这样的:
package main
import "fmt"
func main() {
str := "Hello, 世界"
var counter int
for range str {
counter++
}
fmt.Println(counter)
}
这一个打印 11
直接直接使用 utf8.RuneCountInString()
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
str := "Hello, 世界"
fmt.Println("counts =", utf8.RuneCountInString(str))
}