48
33

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

golangで日本語(マルチバイト)の文字列を数える

Last updated at Posted at 2014-12-16

勢い良くlen()で数えると、byte数になってしまいます。

unicode/utf8 パッケージのRuneCountInString()を使います。
または、[]runeにキャストすることで、len()でも数えられます。

package main

import (
	"fmt"
	"unicode/utf8"
)

func main() {
	str := "Hello, 世界"
	fmt.Printf("len: %d (byte)\n", len(str))
	fmt.Printf("Rune: %d (rune)\n", utf8.RuneCountInString(str))
	fmt.Printf("Rune: %d (rune)\n", len([]rune(str)))
}
len: 13 (byte)
Rune: 9 (rune)
Rune: 9 (rune)

Go Playground

文字数は9文字。len()では13(byte)になり、RuneCountInString()では、期待通り、9が返ってきました。

Hello, まで(半角スペース含む)は、1文字=1byte、日本語は、UTF-8では基本的には3バイトです。ただし、一部のマイナーな漢字は4バイトなので必ずしも3バイトではないです。

ベンチマーク追記

簡単なベンチマークを取ってみました。
上記2つの方法について、ascii/multibyteおよび、文字数(16と32文字)のベンチマークです。

ベンチマークソースはgistにあります。

go test -bench . -benchmem

BenchmarkRunCountInString16ascii	20000000	        79.4 ns/op	       0 B/op	       0 allocs/op
BenchmarkRunCountInString16multi	10000000	       184 ns/op	       0 B/op	       0 allocs/op
BenchmarkRunCountInString32ascii	10000000	       204 ns/op	       0 B/op	       0 allocs/op
BenchmarkRunCountInString32multi	 5000000	       356 ns/op	       0 B/op	       0 allocs/op

BenchmarkCastToRuneArray16ascii	    10000000	       210 ns/op	      64 B/op	       1 allocs/op
BenchmarkCastToRuneArray16multi	     5000000	       312 ns/op	      64 B/op	       1 allocs/op
BenchmarkCastToRuneArray32ascii	     5000000	       362 ns/op	     128 B/op	       1 allocs/op
BenchmarkCastToRuneArray32multi	     5000000	       569 ns/op	     128 B/op	       1 allocs/op

RuneCountInString()のほうが、1.5倍ほど速いです。
ソースを見ると、以下のようになっています。

func RuneCountInString(s string) (n int) {
	for range s {
		n++
	}
	return
}

これだとアロケートは走らないみたいですね。[]runeにキャストするとアロケートされて、その分が遅いんでしょうか。
また、やはりmultiバイトの方が遅かったです。asciiの方が1.5倍ほど速い。

48
33
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
48
33

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?