【Go】strings パッケージ関数まとめ
概要
Go の標準ライブラリである strings
で定義されている各関数の説明とサンプルコードをまとめました。
strings.Reader
, strings.Builder
, strings.Replacer
とこれらに関連する関数はこの記事では対象外とします。
検証した Go のバージョンは以下です。
$ go version
go version go1.15.3 darwin/amd64
Compare(a, b string) int
2つの文字列を辞書的に比較します。
a == b
の場合は 0
, a < b
の場合は -1
, a > b
の場合は 1
を返します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.Compare("aaa", "aaa"))
// => 0
fmt.Println(strings.Compare("aaa", "bbb"))
// => -1
fmt.Println(strings.Compare("bbb", "aaa"))
// => 1
}
Contains(s, substr string) bool
substr
が s
の中に含まれているかどうかを判定します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.Contains("hello world", "h"))
// => true
fmt.Println(strings.Contains("hello world", "hello"))
// => true
fmt.Println(strings.Contains("hello world", "hoge"))
// => false
fmt.Println(strings.Contains("hello world", ""))
// => true
fmt.Println(strings.Contains("", ""))
// => true
}
ContainsAny(s, chars string) bool
chars
に含まれる Unicode コードポイントのいずれかが s
に含まれているかどうかを判定します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.ContainsAny("hello world", "h"))
// => true
fmt.Println(strings.ContainsAny("hello world", "hoge"))
// => true
fmt.Println(strings.ContainsAny("hello world", "AAA"))
// => false
fmt.Println(strings.ContainsAny("hello world", ""))
// => false
fmt.Println(strings.ContainsAny("", ""))
// => false
}
ContainsRune(s string, r rune) bool
s
の中に Unicode コードポイント r
が含まれているかどうかを判定します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.ContainsRune("hello world", 'h'))
// => true
fmt.Println(strings.ContainsRune("hello world", 'A'))
// => false
}
Count(s, substr string) int
s
に含まれている substr
の数をカウントして返します。
substr
が空文字の場合、 s
に含まれている Unicode コードポイントの数 + 1 を返します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.Count("hhh", "h"))
// => 3
fmt.Println(strings.Count("hhhhh", "h"))
// => 5
fmt.Println(strings.Count("hhhhh", ""))
// => 6
}
EqualFold(s, t string) bool
s
と t
を大文字小文字を区別せずに比較します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.EqualFold("Go", "GO"))
// => true
fmt.Println(strings.EqualFold("Go", "gO"))
// => true
fmt.Println(strings.EqualFold("Go", "go"))
// => true
fmt.Println(strings.EqualFold("a", "g"))
// => false
}
Fields(s string) []string
s
を 1 つ以上の空白で分割した文字列のスライスを返します。
s
が空白しか含まれていない、もしくは空文字の場合は空のスライスを返します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Printf("%#v\n", strings.Fields(" hoge fuga\nfoo\tbar\rpiyo "))
// => []string{"hoge", "fuga", "foo", "bar"}
fmt.Printf("%#v\n", strings.Fields(""))
// => []string{}
fmt.Printf("%#v\n", strings.Fields(" \n\t\r"))
// => []string{}
}
FieldsFunc(s string, f func(rune) bool) []string
s
を 1 つ以上の f
を満たす Unicode コードポイントで分割した文字列のスライスを返します。
s
のすべてのコードポイントが f
を満たす、もしくは s
が空文字の場合は空のスライスを返します。
package main
import (
"fmt"
"strings"
)
func main() {
f := func(r rune) bool {
return r == '@'
}
fmt.Printf("%#v\n", strings.FieldsFunc("@@@hoge@@fuga@@@@foo@@bar@@@", f))
// => []string{"hoge", "fuga", "foo", "bar"}
fmt.Printf("%#v\n", strings.FieldsFunc("@@@@", f))
// => []string{}
fmt.Printf("%#v\n", strings.FieldsFunc("", f))
// => []string{}
}
HasPrefix(s, prefix string) bool
s
が prefix
で始まるかどうかを判定します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.HasPrefix("hello world", "h"))
// => true
fmt.Println(strings.HasPrefix("hello world", "hello"))
// => true
fmt.Println(strings.HasPrefix("hello world", "hoge"))
// => false
fmt.Println(strings.HasPrefix("hello world", ""))
// => true
}
HasSuffix(s, suffix string) bool
s
が suffix
で終わるかどうかを判定します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.HasSuffix("hello world", "d"))
// => true
fmt.Println(strings.HasSuffix("hello world", "world"))
// => true
fmt.Println(strings.HasSuffix("hello world", "fuga"))
// => false
fmt.Println(strings.HasSuffix("hello world", ""))
// => true
}
Index(s, substr string) int
s
の中で substr
が最初に見つかる位置を返します。
s
に substr
が含まれていない場合は -1
を返します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.Index("hello world", "h"))
// => 0
fmt.Println(strings.Index("hello world", "hello"))
// => 0
fmt.Println(strings.Index("hello world", "world"))
// => 6
fmt.Println(strings.Index("hello world", "hoge"))
// => -1
fmt.Println(strings.Index("hello world", ""))
// => 0
fmt.Println(strings.Index("", ""))
// => 0
}
IndexAny(s, chars string) int
s
の中で chars
に含まれる Unicode コードポイントのいずれかが最初に見つかる位置を返します。
chars
の中の Unicode コードポイントのどれもが s
に含まれていない場合、 -1
を返します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.IndexAny("hello world", "h"))
// => 0
fmt.Println(strings.IndexAny("hello world", "hoge"))
// => 0
fmt.Println(strings.IndexAny("hello world", "warm"))
// => 6
fmt.Println(strings.IndexAny("hello world", "AAA"))
// => -1
fmt.Println(strings.IndexAny("hello world", ""))
// => -1
fmt.Println(strings.IndexAny("", ""))
// => -1
}
IndexByte(s string, c byte) int
s
の中で c
が最初に見つかる位置を返します。
s
に c
が含まれていない場合、 -1
を返します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.IndexByte("hello world", 'h'))
// => 0
fmt.Println(strings.IndexByte("hello world", 'w'))
// => 6
fmt.Println(strings.IndexByte("hello world", 'a'))
// => -1
}
IndexFunc(s string, f func(rune) bool) int
s
の中で f
を満たす最初の Unicode コードポイントの位置を返します。
s
に f
を満たす Unicode コードポイントが含まれていない場合は -1
を返します。
package main
import (
"fmt"
"strings"
)
func main() {
f := func(r rune) bool {
return r == '@'
}
fmt.Println(strings.IndexFunc("@hello world", f))
// => 0
fmt.Println(strings.IndexFunc("hello@world", f))
// => 5
fmt.Println(strings.IndexFunc("hello world", f))
// => -1
}
IndexRune(s string, r rune) int
s
の中で Unicode コードポイント r
が最初に見つかる位置を返します。
s
に r
が含まれていない場合は -1
を返します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.IndexRune("hello world", 'h'))
// => 0
fmt.Println(strings.IndexRune("hello world", 'w'))
// => 6
fmt.Println(strings.IndexRune("hello world", 'a'))
// => -1
}
Join(elems []string, sep string) string
elems
の要素を sep
で結合して 1 つの文字列を返します。
package main
import (
"fmt"
"strings"
)
func main() {
elems := []string{"hoge", "fuga", "foo", "bar"}
fmt.Println(strings.Join(elems, ","))
// => hoge,fuga,foo,bar
fmt.Println(strings.Join(elems, ""))
// => hogefugafoobar
}
LastIndex(s, substr string) int
s
の中で substr
が最初に見つかる位置を返します。
s
に substr
が含まれていない場合は -1 を返します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.LastIndex("hello hello", "o"))
// => 10
fmt.Println(strings.LastIndex("hello hello", "hello"))
// => 6
fmt.Println(strings.LastIndex("hello hello", "a"))
// => -1
fmt.Println(strings.LastIndex("hello hello", ""))
// => 11
fmt.Println(strings.LastIndex("", ""))
// => 0
}
LastIndexAny(s, chars string) int
s
の中で chars
に含まれる Unicode コードポイントのいずれかが最後に見つかる位置を返します。
chars
の中の Unicode コードポイントのどれもが s
に含まれていない場合は -1
を返します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.LastIndexAny("hello world", "h"))
// => 0
fmt.Println(strings.LastIndexAny("hello world", "world"))
// => 10
fmt.Println(strings.LastIndexAny("hello world", "hoge"))
// => 7
fmt.Println(strings.LastIndexAny("hello world", "AAA"))
// => -1
fmt.Println(strings.LastIndexAny("hello world", ""))
// => -1
fmt.Println(strings.LastIndexAny("", ""))
// => -1
}
LastIndexByte(s string, c byte) int
s
の中で c
が最後に見つかる位置を返します。
s
に c
が含まれていない場合、 -1
を返します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.LastIndexByte("hello world", 'h'))
// => 0
fmt.Println(strings.LastIndexByte("hello world", 'o'))
// => 7
fmt.Println(strings.LastIndexByte("hello world", 'a'))
// => -1
}
LastIndexFunc(s string, f func(rune) bool) int
s
の中で f
を満たす最後の Unicode コードポイントの位置を返します。
s
に f
を満たす Unicode コードポイントが含まれていない場合は -1
を返します。
package main
import (
"fmt"
"strings"
)
func main() {
f := func(r rune) bool {
return r == '@'
}
fmt.Println(strings.LastIndexFunc("@hello world@", f))
// => 12
fmt.Println(strings.LastIndexFunc("hello@world", f))
// => 5
fmt.Println(strings.LastIndexFunc("hello world", f))
// => -1
}
Map(mapping func(rune) rune, s string) string
s
の各文字を mapping
で置換した文字列を返します。
package main
import (
"fmt"
"strings"
)
func main() {
mapping := func(r rune) rune {
return r + 2
}
fmt.Println(strings.Map(mapping, "abc"))
// => cde
}
Repeat(s string, count int) string
s
を count
回繰り返した文字列を返します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.Repeat("a", 5))
// => aaaaa
fmt.Println(strings.Repeat("hello", 5))
// => hellohellohellohellohello
}
Replace(s, old, new string, n int) string
s
の中で old
と一致する文字列を new
に置換します。
n
は置換回数です。
n
に負の値を指定した場合は置換回数に制限はありません ( ReplaceAll
と同義 )。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.Replace("hello hello hello", "hello", "goodnight", -1))
// => goodnight goodnight goodnight
fmt.Println(strings.Replace("hello hello hello", "hello", "goodnight", 0))
// => hello hello hello
fmt.Println(strings.Replace("hello hello hello", "hello", "goodnight", 1))
// => goodnight hello hello
fmt.Println(strings.Replace("aaa", "", "BBB", -1))
// => BBBaBBBaBBBaBBB
}
ReplaceAll(s, old, new string) string
s
の中で old
と一致する全ての文字列を new
に置換します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.ReplaceAll("hello hello hello", "hello", "goodnight"))
// => goodnight goodnight goodnight
fmt.Println(strings.ReplaceAll("aaa", "", "BBB"))
// => BBBaBBBaBBBaBBB
}
Split(s, sep string) []string
s
を sep
で分割したスライスを返します。
s
の中に sep
が含まれていない場合は s
のみを含む長さが 1 のスライスを返します。
sep
が空文字の場合は s
を UTF-8 文字ごとに分割したスライスを返します。
s
と sep
が両方とも空文字の場合は空のスライスを返します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Printf("%#v\n", strings.Split("hoge,fuga,foo,bar", ","))
// => []string{"hoge", "fuga", "foo", "bar"}
fmt.Printf("%#v\n", strings.Split("hoge,fuga,foo,bar", "AAA"))
// => []string{"hoge,fuga,foo,bar"}
fmt.Printf("%#v\n", strings.Split("hoge,fuga,foo,bar", ""))
// => []string{"h", "o", "g", "e", ",", "f", "u", "g", "a", ",", "f", "o", "o", ",", "b", "a", "r"}
fmt.Printf("%#v\n", strings.Split("", ""))
// => []string{}
}
SplitAfter(s, sep string) []string
s
を sep
の後で分割したスライスを返します。
s
の中に sep
が含まれていない場合は s
のみを含む長さが 1 のスライスを返します。
sep
が空文字の場合は s
を UTF-8 文字ごとに分割したスライスを返します。
s
と sep
が両方とも空文字の場合は空のスライスを返します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Printf("%#v\n", strings.SplitAfter("hoge-fuga-foo-bar", "-"))
// => []string{"hoge-", "fuga-", "foo-", "bar"}
fmt.Printf("%#v\n", strings.SplitAfter("hoge,fuga,foo,bar", "AAA"))
// => []string{"hoge,fuga,foo,bar"}
fmt.Printf("%#v\n", strings.SplitAfter("hoge,fuga,foo,bar", ""))
// => []string{"h", "o", "g", "e", ",", "f", "u", "g", "a", ",", "f", "o", "o", ",", "b", "a", "r"}
fmt.Printf("%#v\n", strings.SplitAfter("", ""))
// => []string{}
}
SplitAfterN(s, sep string, n int) []string
s
を sep
の後で分割したスライスを返します。
n
は s
を分割する数を設定します。
n
に負の数を指定した場合は SplitAfter
と同義です。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Printf("%#v\n", strings.SplitAfterN("hoge-fuga-foo-bar", "-", 2))
// => []string{"hoge-", "fuga-foo-bar"}
fmt.Printf("%#v\n", strings.SplitAfterN("hoge-fuga-foo-bar", "-", -1))
// => []string{"hoge-", "fuga-", "foo-", "bar"}
fmt.Printf("%#v\n", strings.SplitAfterN("hoge,fuga,foo,bar", "AAA", 2))
// => []string{"hoge,fuga,foo,bar"}
fmt.Printf("%#v\n", strings.SplitAfterN("hoge,fuga,foo,bar", "", 2))
// => []string{"h", "oge,fuga,foo,bar"}
fmt.Printf("%#v\n", strings.SplitAfterN("", "", 2))
// => []string{}
}
SplitN(s, sep string, n int) []string
s
を sep
で分割したスライスを返します。
n
は s
を分割する数を設定します。
n
に負の数を指定した場合は Split
と同義です。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Printf("%#v\n", strings.SplitN("hoge,fuga,foo,bar", ",", 2))
// => []string{"hoge", "fuga,foo,bar"}
fmt.Printf("%#v\n", strings.SplitN("hoge,fuga,foo,bar", ",", -1))
// => []string{"hoge", "fuga", "foo", "bar"}
fmt.Printf("%#v\n", strings.SplitN("hoge,fuga,foo,bar", "AAA", 2))
// => []string{"hoge,fuga,foo,bar"}
fmt.Printf("%#v\n", strings.SplitN("hoge,fuga,foo,bar", "", 2))
// => []string{"h", "oge,fuga,foo,bar"}
fmt.Printf("%#v\n", strings.SplitN("", "", 2))
// => []string{}
}
Title(s string) string
s
をタイトルケースに変換した文字列を返します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.Title("hello world"))
// => Hello World
fmt.Println(strings.Title("hoge fuga foo bar"))
// => Hoge Fuga Foo Bar
}
ToLower(s string) string
s
の文字を全て小文字に変換した文字列を返します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.ToLower("HELLO WORLD"))
// => hello world
fmt.Println(strings.ToLower("HOGE FUGA FOO BAR"))
// => hoge fuga foo bar
}
ToLowerSpecial(c unicode.SpecialCase, s string) string
s
の文字を全てケースマッピング c
を用いて小文字に変換した文字列を返します。
package main
import (
"fmt"
"strings"
"unicode"
)
func main() {
fmt.Println(strings.ToLowerSpecial(unicode.TurkishCase, "Önnek İş"))
// => önnek iş
}
ToTitle(s string) string
s
の文字を全てタイトルケースに変換した文字列を返します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.ToTitle("hello world"))
// => HELLO WORLD
fmt.Println(strings.ToTitle("hoge fuga foo bar"))
// => HOGE FUGA FOO BAR
}
ToTitleSpecial(c unicode.SpecialCase, s string) string
s
の文字を全てケースマッピング c
を用いてタイトルケースに変換した文字列を返します。
package main
import (
"fmt"
"strings"
"unicode"
)
func main() {
fmt.Println(strings.ToTitleSpecial(unicode.TurkishCase, "önnek iş"))
// => ÖNNEK İŞ
}
ToUpper(s string) string
s
の文字を全て大文字に変換した文字列を返します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.ToUpper("hello world"))
// => HELLO WORLD
fmt.Println(strings.ToUpper("hoge fuga foo bar"))
// => HOGE FUGA FOO BAR
}
ToUpperSpecial(c unicode.SpecialCase, s string) string
s
の文字を全てケースマッピング c
を用いて大文字に変換した文字列を返します。
package main
import (
"fmt"
"strings"
"unicode"
)
func main() {
fmt.Println(strings.ToUpperSpecial(unicode.TurkishCase, "önnek iş"))
// => ÖNNEK İŞ
}
ToValidUTF8(s, replacement string) string
s
の中の無効な UTF-8 バイトシーケンスを replacement
に置換した文字列を返します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.ToValidUTF8("hello world", " "))
// => hello world
fmt.Println(strings.ToValidUTF8("hello \xc5", "world"))
// => hello world
}
Trim(s, cutset string) string
s
の先頭と末尾から cutset
に含まれる Unicode コードポイントを除いた文字列を返します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.Trim("!!!@@@hello@!world!!!@@@", "@!"))
// => hello@!world
}
TrimFunc(s string, f func(rune) bool) string
s
の先頭と末尾から f
を満たす Unicode コードポイントを除いた文字列を返します。
package main
import (
"fmt"
"strings"
)
func main() {
f := func(r rune) bool {
return r == '@'
}
fmt.Println(strings.TrimFunc("@@@hello@world@@@", f))
// => hello@world
}
TrimLeft(s, cutset string) string
s
の先頭から cutset
に含まれる Unicode コードポイントを除いた文字列を返します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.TrimLeft("!!!@@@hello@!world!!!@@@", "@!"))
// => hello@!world!!!@@@
}
TrimLeftFunc(s string, f func(rune) bool) string
s
の先頭から f
を満たす Unicode コードポイントを除いた文字列を返します。
package main
import (
"fmt"
"strings"
)
func main() {
f := func(r rune) bool {
return r == '@'
}
fmt.Println(strings.TrimLeftFunc("@@@hello@world@@@", f))
// => hello@world@@@
}
TrimPrefix(s, prefix string) string
s
から接頭辞 prefix
を除いた文字列を返します。
s
が prefix
から始まらない場合は s
をそのまま返します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.TrimPrefix("helloworld", "hello"))
// => world
fmt.Println(strings.TrimPrefix("helloworld", "world"))
// => helloworld
}
TrimRight(s, cutset string) string
s
の末尾から cutset
に含まれる Unicode コードポイントを除いた文字列を返します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.TrimRight("!!!@@@hello@!world!!!@@@", "@!"))
// => !!!@@@hello@!world
}
TrimRightFunc(s string, f func(rune) bool) string
s
の末尾から f
を満たす Unicode コードポイントを除いた文字列を返します。
package main
import (
"fmt"
"strings"
)
func main() {
f := func(r rune) bool {
return r == '@'
}
fmt.Println(strings.TrimRightFunc("@@@hello@world@@@", f))
// => @@@hello@world
}
TrimSpace(s string) string
s
の先頭と末尾から空白を除いた文字列を返します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Printf("%#v\n", strings.TrimSpace(" \r\n\thello world\t\n\r "))
// => "hello world"
}
TrimSuffix(s, suffix string) string
s
から接尾辞 suffix
を除いた文字列を返します。
s
が suffix
で終わらない場合は s
をそのまま返します。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.TrimSuffix("helloworld", "world"))
// => hello
fmt.Println(strings.TrimSuffix("helloworld", "hello"))
// => helloworld
}
まとめ
結果として 公式ドキュメント の内容をほとんどそのまま写しただけみたいな記事になってしまいましたが、実際にコードを書いて動きを見てみることでいい勉強になりました。
参考
Discussion