文字列操作と関連パッケージ(fmt, strings, strconv)

Goの文字列操作について確認します。マルチバイト文字列を扱うときの注意点や、文字列操作で役立つパッケージ(fmt, strings, strconv, regexp)について取り上げます。

文字列操作の基礎

string型とrune型

ダブルクォーテーションで囲むとstring型になります。シングルクオートだとrune型になります。

package main

import (
	"fmt"
)

func main() {
	var (
		s1 string = "abcdefg"
		s2 string = "あいうえお"

		s3 rune = 'a'
		s4 rune = 'あ'
	)

	fmt.Println(s1, s2, s3, s4, string(s3), string(s4))
}
abcdefg あいうえお 97 12354 a あ

文字列長を取得

マルチバイト文字の場合、rune型にしてからlen関数で取得します。

package main

import (
	"fmt"
)

func main() {
	var (
		// 文字列はダブルクォーテーション
		s1 string = "abcdefg"
		s2 string = "あいうえお"
	)

	fmt.Println(len(s1), len([]rune(s1)))
	fmt.Println(len(s2), len([]rune(s2)))
}
7 7
15 5

文字へのアクセス

アルファベットは1文字1バイトですが、日本語はほぼ1文字3バイトです。
マルチバイト文字は、rune型に変換すると操作しやすくなります。

package main

import (
	"fmt"
)

func main() {
	const (
		s1 string = "abcdefg"
		s2 string = "あいうえお"
	)

	fmt.Println("------------------------")
	fmt.Println(s1[0:1])
	fmt.Println(s1[:3])
	fmt.Println(s1[3:])
	fmt.Println(s1[3:4])

	fmt.Println("------------------------")
	fmt.Println(s2[:3])
	fmt.Println(s2[3:6])
	fmt.Println(s2[6:12])
	fmt.Println(s2[6:12])

	fmt.Println("------------------------")
	r := []rune(s2)
	fmt.Println(string(r[0:1]))
	fmt.Println(string(r[:3]))
	fmt.Println(string(r[3:]))
	fmt.Println(string(r[3:4]))
}
------------------------
a
abc
defg
d
------------------------
あ
い
うえ
うえ
------------------------
あ
あいう
えお
え

エスケープシーケンス

package main

import (
	"fmt"
)

func main() {
	fmt.Println("改行: aa\naa")
	fmt.Println("--------------------------")
	fmt.Println("水平タブ: aa\taa")
	fmt.Println("--------------------------")
	fmt.Println("垂直タブ: aa\vaa")
	fmt.Println("--------------------------")
	fmt.Println("ダブルクォーテーション: aa\"aa")
	fmt.Println("--------------------------")
	fmt.Println("バックスラッシュ: aa\\aa")
}
改行: aa
aa
--------------------------
水平タブ: aa    aa
--------------------------
垂直タブ: aa
            aa
--------------------------
ダブルクォーテーション: aa"aa
--------------------------
バックスラッシュ: aa\aa

文字列連結

+演算子 で連結できます。

package main

import (
	"fmt"
)

func main() {
	s1 := "わくわく"
	s2 := "Bank"
	s := s1 + s2
	fmt.Println(s)
}
わくわくBank

fmt package

package main

import "fmt"

func main() {
	s := "abcdef"
	fmt.Printf("value:%v type:%T\n", s, s)

	s1 := fmt.Sprintf("value:%v type:%T\n", s, s)
	fmt.Print(s1)
}
Hello World.
aaabbb
aaabbbccc
Hello World.
aaabbb
aaabbbccc

Println, Sprintln

package main

import "fmt"

func main() {
	fmt.Println("Hello World.")
	fmt.Println("aaa", "bbb")
	fmt.Println("aaa", "bbb", "ccc")

	s1 := fmt.Sprintln("Hello World.")
	fmt.Print(s1)
	s2 := fmt.Sprintln("aaa", "bbb")
	fmt.Print(s2)
	s3 := fmt.Sprintln("aaa", "bbb", "ccc")
	fmt.Print(s3)
}
Hello World.
aaa bbb
aaa bbb ccc
Hello World.
aaa bbb
aaa bbb ccc

Printf, Sprintf

package main

import "fmt"

func main() {
	s := "abcdef"
	fmt.Printf("value:%v type:%T\n", s, s)

	s1 := fmt.Sprintf("value:%v type:%T\n", s, s)
	fmt.Print(s1)
}
value:abcdef type:string
value:abcdef type:string
package main

import "fmt"

func main() {
	b := true
	fmt.Printf("boolean:%t\n", b)

	i := 10
	fmt.Printf("2進数:%b\n", i)
	fmt.Printf("8進数:%o\n", i)
	fmt.Printf("10進数:%d\n", i)
	fmt.Printf("16進数:%x\n", i)

	f := 3.1415
	fmt.Printf("%f\n", f)
	fmt.Printf("%.4f\n", f)
	fmt.Printf("%10.4f\n", f)
	fmt.Printf("%010.4f\n", f)
}
boolean:true
2進数:1010
8進数:12
10進数:10
16進数:a
3.141500
3.1415
    3.1415
00003.1415

strings package

stringsパッケージで利用頻度の高そうなメソッドを抜粋します。Exampleが掲載されており、動作確認できます。

strconv package

strconvパッケージで利用頻度の高そうなメソッドを抜粋します。Exampleが掲載されており、動作確認できます。

regexp package

Goの正規表現は遅いと言われており、まずはstringsパッケージで実装できないか検討することをお勧めします。

regexpパッケージで利用頻度の高そうなメソッドを抜粋します。Exampleが掲載されており、動作確認できます。

参考