PR

Go言語(Golang)の「strings」パッケージの使い方|実務で使う可能性が高い関数を中心にサンプルコードで解説

2. 基礎

こんにちは。Tomoyuki(@tomoyuki65)です。

Go言語(Golang)には文字列を操作するための標準パッケージとして、「strings」パッケージがあります。

ただし、関数の種類が多く、全てを覚えようとするのは大変なため、まずは実務でよく使う可能性が高い関数を中心に学ぶのがおすすめです。

この記事では、そんな「strings」パッケージにおいて、実務でよく使う可能性が高い関数を中心にご紹介します。

 

Go言語(Golang)の「strings」パッケージの使い方|実務で使う可能性が高い関数を中心にサンプルコードで解説

「strings」パッケージには様々な関数がありますが、まずは実務でよく使われる可能性が高い以下の10個について学びましょう。

 

TrimSpace:入力値の空白除去

文字列の先頭と末尾にある空白文字を取り除きたい場合は、TrimSpace関数を利用すると可能です。

package main

import (
    "fmt"
    "strings"
)

func main() {
    text := " Hello World "

    // 先頭と末尾にある空白除去
    result := strings.TrimSpace(text)

    // ログ出力
    fmt.Println(result)
}

※文字列の途中にある空白は除去しません。タブ(\t)や改行(\n)も除去します。

 

実行結果

Hello World

 

Contains:文字列の存在チェック

対象の文字列に対して、指定した文字列が含まれているかを判定したい場合は、Contains関数を利用すると可能です。

package main

import (
    "fmt"
    "strings"
)

func main() {
    text := "Hello World !!"

    // 文字列の存在チェック
    result := strings.Contains(text, "World")

    // ログ出力
    fmt.Println(result)
}

※大文字・小文字は区別します。

 

実行結果

true

 

HasPrefix:プレフィックスのチェック

対象の文字列が指定した文字列から始まっているかを判定したい場合は、HasPrefix関数を利用すると可能です。

package main

import (
    "fmt"
    "strings"
)

func main() {
    text := "https://example.com"

    // プレフィックスのチェック
    result := strings.HasPrefix(text, "https://")

    // ログ出力
    fmt.Println(result)
}

※文字列の先頭をチェックするため、URLや文字列の形式チェックに便利です。

 

実行結果

true

 

HasSuffix:サフィックスのチェック

対象の文字列が指定した文字列で終わっているかを判定したい場合は、HasSuffix関数を利用すると可能です。

package main

import (
    "fmt"
    "strings"
)

func main() {
    text := "image.png"

    // サフィックスのチェック
    result := strings.HasSuffix(text, ".png")

    // ログ出力
    fmt.Println(result)
}

※文字列の末尾をチェックするため、ファイルの拡張子判定などに便利です。

 

実行結果

true

 

ReplaceAll:文字列の一括置換

対象の文字列の中から指定した文字列を検索し、指定した文字列へ一括変換したい場合は、ReplaceAll関数を利用すると可能です。

package main

import (
    "fmt"
    "strings"
)

func main() {
    text := "リンゴ バナナ リンゴ ぶどう"

    // 文字列の一括置換
    result := strings.ReplaceAll(text, "リンゴ", "オレンジ")

    // ログ出力
    fmt.Println(result)
}

※対象の文字列を全て置換し、新しい文字列として返します。(元の文字列は変更されない)もし一部だけ置換したい場合は、Replace関数を使います。

 

実行結果

オレンジ バナナ オレンジ ぶどう

 

Split:文字列の分割

対象の文字列に対し、指定した区切り文字を使って文字列を分割したい場合は、Split関数を利用すると可能です。

package main

import (
    "fmt"
    "strings"
)

func main() {
    text := "リンゴ,バナナ,オレンジ"

    // 区切り文字で文字列を分割
    result := strings.Split(text, ",")

    // ログ出力
    fmt.Println(result)
}

※戻り値は文字列のスライス([]string)で返す。CSVのような区切り形式の文字列を扱う際に便利です。

 

実行結果

[リンゴ バナナ オレンジ]

 

Join:区切り文字で一つの文字列に結合

文字列のスライス([]string)に対して、指定した区切り文字で一つの文字列に結合したい場合は、Join関数を利用すると可能です。

package main

import (
    "fmt"
    "strings"
)

func main() {
    items := []string{"リンゴ", "バナナ", "オレンジ"}

    // 区切り文字で一つの文字列に結合
    result := strings.Join(items, ", ")

    // ログ出力
    fmt.Println(result)
}

 

実行結果

リンゴ, バナナ, オレンジ

 

ToLower:アルファベットを小文字に変換

対象の文字列に含まれるアルファベットを小文字に変換したい場合は、ToLower関数を利用すると可能です。

package main

import (
    "fmt"
    "strings"
)

func main() {
    text := "Hello WORLD !!"

    // アルファベットを小文字に変換
    result := strings.ToLower(text)

    // ログ出力
    fmt.Println(result)
}

※Unicodeの大文字にも対応しています。もし逆に大文字に変換したい場合は、ToUpper関数を使います。

 

実行結果

hello world !!

 

Cut:区切り文字を基準に文字列を前後に分割(キーと値などに分離)

対象の文字列を指定した区切り文字を基準に文字列を前後に分割(キーと値などに分離)したい場合は、Cut関数を利用すると可能です。

package main

import (
    "fmt"
    "strings"
)

func main() {
    text := "name=田中"

    // 区切り文字を基準に文字列を前後に分割
    key, value, found := strings.Cut(text, "=")

    // ログ出力
    fmt.Println(key)
    fmt.Println(value)
    fmt.Println(found)
}

※最初に見つかった区切り文字で分割します。区切り文字が見つからない場合は、元の文字列がkeyに入り、valueは空文字になり、foundがfalseになります。

 

実行結果

name
田中
true

 

Builder:文字列の効率的な組み立て

文字列を効率的に組み立てたい場合は、Builder関数を利用すると可能です。

package main

import (
    "fmt"
    "strings"
)

func main() {
    // Builder構造体の変数を定義
    var b strings.Builder

    // 内部バッファに文字列を追加
    b.WriteString("Hello")
    b.WriteString(" ")
    b.WriteString("World")
    b.WriteString(" ")
    b.WriteString("!!")

    // 組み立てた文字列を取得
    result := b.String()

    // ログ出力
    fmt.Println(result)
}

※内部バッファを利用するため、繰り返しの文字列結合よりメモリコピーを抑えられるのがメリットです。また、文字列を追加する際に必要に応じて内部バッファが拡張される仕様になっていますが、事前に文字列の最大値を見積もれる場合は、Grow(n)メソッドを利用することで、バッファの再確保やデータコピーを減らせる可能性があります。

 

実行結果

Hello World !!

 

また、ループ処理での使用例は以下の通りです。

package main

import (
    "fmt"
    "strings"
)

func main() {
    items := []string{"リンゴ", "バナナ", "オレンジ"}

    // 文字列の組み立て
    var b strings.Builder

    for _, item := range items {
        b.WriteString(item)
        b.WriteString("\n")
    }

    // ログ出力
    fmt.Println(b.String())
}

 

実行結果

リンゴ
バナナ
オレンジ

 

スポンサーリンク

その他の「strings」パッケージの関数一覧

文字列の検索・位置取得

関数 概要 使用例
Index 指定した文字列が最初に出現する位置を取得 strings.Index(“hello”, “l”) → 2
LastIndex 指定した文字列が最後に出現する位置を取得 strings.LastIndex(“hello”, “l”) → 3
IndexAny 指定した文字のいずれかが最初に出現する位置を取得 strings.IndexAny(“hello”, “ae”) → 1
LastIndexAny 指定した文字のいずれかが最後に出現する位置を取得 strings.LastIndexAny(“hello”, “el”) → 3
IndexByte 指定した1バイトの文字が最初に出現する位置を取得 strings.IndexByte(“hello”, ‘l’) → 2
LastIndexByte 指定した1バイトの文字が最後に出現する位置を取得 strings.LastIndexByte(“hello”, ‘l’) → 3
IndexRune 指定したUnicode文字が最初に出現する位置を取得 strings.IndexRune(“こんにちは”, ‘に’) → 6
IndexFunc 条件を満たす最初のUnicode文字の位置を取得 strings.IndexFunc(“hello”, unicode.IsUpper) → -1
LastIndexFunc 条件を満たす最後のUnicode文字の位置を取得 strings.LastIndexFunc(“hello!”, unicode.IsPunct) → 5
Count 指定した文字列の出現回数を取得 strings.Count(“hello”, “l”) → 2
ContainsAny 指定した文字のいずれかが含まれているか判定 strings.ContainsAny(“hello”, “ae”) → true
ContainsRune 指定したUnicode文字が含まれているか判定 strings.ContainsRune(“こんにちは”, ‘に’) → true
ContainsFunc 条件を満たすUnicode文字が含まれているか判定 strings.ContainsFunc(“hello”, unicode.IsUpper) → false

 

文字列の加工・変換

関数 概要 使用例
Replace 指定した文字列を回数指定して置換 strings.Replace(“aaa”, “a”, “b”, 2) → “bba”
ToUpper 大文字に変換 strings.ToUpper(“hello”) → “HELLO”
ToUpperSpecial Unicodeの特定の規則に従って大文字に変換 strings.ToUpperSpecial(…)
ToLowerSpecial Unicodeの特定の規則に従って小文字に変換 strings.ToLowerSpecial(…)
ToTitle Unicodeのタイトルケースに変換 strings.ToTitle(“hello”) → “HELLO”
ToTitleSpecial Unicodeの特定の規則に従ってタイトルケースに変換 strings.ToTitleSpecial(…)
Map 各Unicode文字を指定した関数で変換 strings.Map(func(r rune) rune { return unicode.ToUpper(r) }, “hello”)
Repeat 指定した回数だけ文字列を繰り返す strings.Repeat(“Go”, 3) → “GoGoGo”
Trim 先頭・末尾にある指定文字を削除 strings.Trim(“!!hello!!”, “!”) → “hello”
TrimLeft 先頭にある指定文字を削除 strings.TrimLeft(“!!hello”, “!”) → “hello”
TrimRight 末尾にある指定文字を削除 strings.TrimRight(“hello!!”, “!”) → “hello”
TrimFunc 条件を満たす先頭・末尾のUnicode文字を削除 strings.TrimFunc(“!!hello!!”, unicode.IsPunct) → “hello”
TrimLeftFunc 条件を満たす先頭のUnicode文字を削除 strings.TrimLeftFunc(“!!hello”, unicode.IsPunct) → “hello”
TrimRightFunc 条件を満たす末尾のUnicode文字を削除 strings.TrimRightFunc(“hello!!”, unicode.IsPunct) → “hello”
TrimPrefix 先頭にある指定文字列を削除 strings.TrimPrefix(“hello.go”, “hello.”) → “go”
TrimSuffix 末尾にある指定文字列を削除 strings.TrimSuffix(“hello.go”, “.go”) → “hello”
ToValidUTF8 不正なUTF-8文字列を指定文字列に置き換える strings.ToValidUTF8(“a\xffb”, “?”) → “a?b”
Clone 文字列を新しいメモリ領域にコピー strings.Clone(“hello”) → “hello”

 

文字列の分割・抽出

関数 概要 使用例
SplitN 指定した区切り文字で分割し、最大分割数を指定 strings.SplitN(“a,b,c”, “,”, 2) → [“a”, “b,c”]
SplitAfter 区切り文字を残した状態で分割 strings.SplitAfter(“a,b,c”, “,”) → [“a,”, “b,”, “c”]
SplitAfterN 区切り文字を残して、最大分割数を指定 strings.SplitAfterN(“a,b,c”, “,”, 2) → [“a,”, “b,c”]
Fields 空白文字を区切りとして文字列を分割 strings.Fields(“hello world”) → [“hello”, “world”]
FieldsFunc 指定した条件を区切りとして文字列を分割 strings.FieldsFunc(“a,b;c”, …) → [“a”, “b”, “c”]
Lines 改行単位で文字列をイテレータとして取得 strings.Lines(“a\nb\n”)
CutLast 最後に出現する区切り文字を基準に文字列を分割 strings.CutLast(“a/b/c”, “/”) → “a/b”, “c”, true

 

文字列の比較

関数 概要 使用例
Compare 文字列を辞書順で比較 strings.Compare(“a”, “b”) → -1
EqualFold 大文字・小文字を区別せずに文字列を比較 strings.EqualFold(“Go”, “go”) → true

 

その他の便利な機能

関数 概要 使用例
NewReplacer 複数の文字列置換ルールをまとめて定義 strings.NewReplacer(“a”, “A”, “b”, “B”)
FieldsSeq 空白区切りの文字列をイテレータで取得 strings.FieldsSeq(“hello world”)
FieldsFuncSeq 条件に基づいて分割した文字列をイテレータで取得 strings.FieldsFuncSeq(“a,b;c”, …)
SplitSeq 区切り文字で分割した文字列をイテレータで取得 strings.SplitSeq(“a,b,c”, “,”)
SplitAfterSeq 区切り文字を残して分割した文字列をイテレータで取得 strings.SplitAfterSeq(“a,b,c”, “,”)

 

スポンサーリンク

最後に

今回は「strings」パッケージにおいて、実務でよく使う可能性が高い関数を中心にご紹介しました。

利用できる関数が非常に多く、文字列に対して様々な処理が可能ですが、全てを一気に覚える必要はないため、まずは実務でよく使う可能性が高い関数を中心に学びましょう。

これからstringsパッケージの使い方を学ぶ方は、ぜひ参考にしてみて下さい。

 

SubstackでITエンジニア向けニュースレター(メルマガ)を始めました!
こんにちは。Tomoyuki(@tomoyuki65)です。最近はどのSNSもアルゴリズム(どの投稿を誰に表示するかを決める仕組み)中心のタイムライン(投稿が流れてくる画面)になっていて、フォローしている人の投稿が見つけにくく、逆にフォロー...

 

この記事を書いた人
Tomoyuki

SE→ブロガーを経て、現在はSoftware Engineer(Web/Gopher)をしています!

Tomoyukiをフォローする
2. 基礎
スポンサーリンク
Tomoyukiをフォローする

コメント

タイトルとURLをコピーしました