【Go言語】文字列を比較する方法と文字列を置換する方法。正規表現にReplace関数、MustCompile関数を使う

Go言語での文字列を比較する方法と、文字列の置換をする方法について説明します。

細かい補足も付けてますので、細かく読んでもらえたら知識がかなり深まると思います。

 

Go言語で文字列を比較する方法

文字列の比較には==演算子やstringsパッケージのEquals関数を使います。

==演算子は文字列のバイト列が完全に一致するかどうかを判定します。普通はこちらを使うほうが書き慣れていると思います。

EqualFold関数は文字列のrune(文字)が同じかどうかを判定します。また注意点として、この関数では大文字・小文字の違いが無視されます

以下がGo言語で文字列を比較するときのサンプルコードです。


package main

import (
    "fmt"
    "strings"
)

func main() {
    s1 := "こんにちは"
    s2 := "こんばんは"
    s3 := "こんにちは”

    // ==演算子で比較
    fmt.Println(s1 == s2) // false
   fmt.Println(s1 == s3) // true

    // Equals関数で比較
    fmt.Println(strings.EqualFold(s1, s2)) // false
    fmt.Println(strings.EqualFold(s1, s3)) // true

    // 大文字、小文字が無視されることに注意
    fmt.Println(strings.EqualFold("AB", "ab")) // true
}

 

Go言語で文字列の置換をする方法|正規表現も

Go言語で文字列の置換をするにはstringsパッケージのReplace関数やReplaecAll関数、regexpパッケージのReplaceAllString関数を使います。

Replace関数は文字列の中の指定した部分文字列を別の文字列に置き換えます。置き換える回数を指定できます。もし一致する全ての文字を置換する場合にはReplaceAll関数を使います。

置き換える文字列が固定されている場合にはこちらを使います。

置き換える文字が動的に変わる場合には正規表現を使って文字列置換をします。ReplaceAllString関数は正規表現でマッチする部分の文字列を別の文字列に置換します。

以下がGo言語の文字列置換のサンプルコードです。


package main

import (
    "fmt"
    "strings"
    "regexp"
)

func main() {
    s := "Hello, world!"
    s2 := "Hello, Hello, world!"

    // Replace関数で置換
    fmt.Println(strings.Replace(s, "world", "golang", 1)) // Hello, golang!

    // すべてを一括で置換する
    fmt.Println(strings.ReplaceAll(s2, "Hello", "Wow")) // Wow, Wow, World!

    // ReplaceAllString関数で置換
    fmt.Println(regexp.MustCompile("[aiueo]").ReplaceAllString(s, "*")) // H*ll*, w*rld!
}

 

MustCompile関数の注意点

MustCompile関数について補足しておきます。正規表現の当て方が動的に変わる場合には注意が必要ということです。

この関数は前述の通りに正規表現のパターンを指定するとRegexp型のオブジェクトを返します。正規表現の解析に失敗したときはpanicを発生します。

package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`[a-z]+`)
    s := "Hello, world!"

    // 正規表現にマッチする部分文字列を抽出
    fmt.Println(re.FindAllString(s, -1)) // [ello world]
}

つまりMustCompile関数は正規表現のパターンが固定である場合に便利です。

もし正規表現パターンが動的に変わる場合はCompile関数を使ってエラーをハンドリングする必要があります。

同じregexpパッケージにあるCompile関数はRegexp型のオブジェクトとエラーも返します。このerrをハンドリングすることで正規表現のミスを防ぐことができます。

サンプルコードです。


package main

import (
    "fmt"
    "regexp"
)

func main() {
    // 正規表現のオブジェクトとエラーを返す
    re, err := regexp.Compile(`[a-z]+`)

    // エラーハンドリングできる!
    if err != nil {
        fmt.Println(err)
        return
    }

    s := "Hello, world!"

    // 正規表現にマッチする部分文字列を抽出
    fmt.Println(re.FindAllString(s, -1)) // [ello world]
}