目次
日本語文字列に対し頻繁に使う文字列操作
日本語文字列に対し頻繁に使う「文字列」操作ができるか?を確認します。
確認方法
正規表現は使いません。
確かめるのに使う文字列です。
var s = " 漢字123456abcdefGHIJKLひらがなカタカナハンカナ混在 "
半角全角の英数字かなカナ漢字混在で、前に半角空白、後ろに全角空白があります。
確かめは、こんな感じでソースコードを書いてやってます。
package main import ( "fmt" "strings" ) func main() { var s string = " 漢字123456abcdefGHIJKLひらがなカタカナハンカナ混在 " ps := strings.TrimSpace(s) fmt.Print(ps) }
さて、やってみます。
トリム(前後の空白を削除)
"strings"をimportして、以下のようにします。
ps := strings.TrimSpace(s)
結果は こう。
漢字123456abcdefGHIJKLひらがなカタカナハンカナ混在
両端の半角も全角も空白が削除されてます。
大文字変換
"strings"をimportして、以下のようにします。
ps := strings.ToUpper(s)
半角も全角も大文字変換されます。
漢字123456ABCDEFGHIJKLひらがなカタカナハンカナ混在
小文字変換
"strings"をimportして、以下のようにします。
ps := strings.ToLower(s)
半角も全角も小文字変換されます。
漢字123456abcdefghijklひらがなカタカナハンカナ混在
全角変換・半角変換
golang.org/x/text/widthをimportします。
importエラーになるときは、「go get」でローカルにインストールします。
(たぶん、VSCodeが候補を表示してくれますけど)
全角変換は以下のようなソースになります。
package main import ( "fmt" "golang.org/x/text/width" ) func main() { var s string = " 漢字123456abcdefGHIJKLひらがなカタカナハンカナ混在 " ps := width.Widen.String(s) fmt.Print(ps) }
結果は半角カナも含めて、全角になってます。
漢字123456abcdefGHIJKLひらがなカタカナハンカナ混在
半角変換は、WidenをNarrowに変えます。
ps := width.Narrow.String(s)
漢字とひらがな以外は半角になります。
カナが半角カナになっているのがすごいです。
漢字123456abcdefGHIJKLひらがなカタカナハンカナ混在
全角・半角変換のひとつの目的として、文字列比較の前処理があります。
それに便利そうな、 Foldというのも使えます。
ps := width.Fold.String(s)
漢字・ひらがな・カタカナを全角に、英数字を半角に統一してくれます。
ちょうど「いい塩梅の変換」だと自分は思います。
結果はこうです。
漢字123456abcdefGHIJKLひらがなカタカナハンカナ混在
数字から文字列へ返還
"strconv"をimportします。
整数を文字列にするのは「Itoa」
i := 12345 ps := strconv.Itoa(i)
浮動小数点数を文字列には「FormatFloat」。3つ目の引数で小数点以下の桁数です。
j := 1234.567 ps = strconv.FormatFloat(j, 'f', 6, 64)
それぞれの結果が
12345
1234.567000
strconvはほかにもいろいろあります。
文字列からboolやfloatなどにパースするパターン、
b, err := strconv.ParseBool("true")
f, err := strconv.ParseFloat("3.1415", 64)
i, err := strconv.ParseInt("-42", 10, 64)
u, err := strconv.ParseUint("42", 10, 64)
逆に文字列にフォーマットするパターン。
s := strconv.FormatBool(true)
s := strconv.FormatFloat(3.1415, 'E', -1, 64)
s := strconv.FormatInt(-42, 16)
s := strconv.FormatUint(42, 16)
などなど。
文字列の分割
"strings"をimportして、以下のようにします。
「c」で文字列を2つに分割して、[]をつけて表示してみます。
ps := strings.Split(s, "c") for _, str := range ps { fmt.Printf("[%s]", str) }
「c」がセパレータになって2分割されてます。
[ 漢字123456ab][defGHIJKLひらがなカタカナハンカナ混在 ]
文字列の切り出し(スライス)
文字列をスライスで切り出すことができます。
ps := s[4:10] ps = s[:4] ps = s[16:]
[開始:終了]で指定しますが、開始は0から始まり、開始から終了の前のバイトまで取得しますが、ちょっと癖があります。
- 半角文字:1文字1バイト
- 全角文字:1文字3バイト
で計算して位置を決めないといけません。
開始を未指定は先頭から、終了未指定は最後まで・・になります。
なので、上記の結果は以下のようになります。
字123
漢
6abcdefGHIJKLひらがなカタカナハンカナ混在
文字列の連結
文字列を「+」でぺたぺた連結できます。
i := 12345 j := 4567.34 ps := "整数を文字列に「" + strconv.Itoa(i) + "」+浮動小数点を文字列に「" + strconv.FormatFloat(j, 'f', 6, 64) + "」"
結果はこう。
整数を文字列に「12345」+浮動小数点を文字列に「4567.340000」
文字列中に指定文字列が含まれるか検査
strings.containsを使います。
b := strings.Contains(s, "がな")
結果はtrue、falseで戻されます。
文字列中の指定文字列の出現位置
stringsのIndex(最初の位置)、LastIndex(最後の位置)を使います。
var s string = "僕の「かばん」と君の「かばん」は同じ「かばん」なのか?" idx := strings.Index(s, "「かばん」") lidx := strings.LastIndex(s, "「かばん」")
これで結果が最初の位置が「6」、最後の位置が「54」とかえってきます。
文字数ではなく、全部全角文字なので、1文字=3バイト計算です。
文字列の長さ
len()を使います。
l := len("「かばん」")
これで結果は「15」と返ります。
これも「全角文字=3バイト」として計算しているからです。
全角文字5文字 = 3 × 5 = 15・・ということです。
文字列のスライスに使うなら、まあ、こうなってないとな・・という感じです。
これはいやだな・・文字数を数えたい・・場合は、こんなやり方になります。
l := len([]rune("「かばん」"))
こうすると文字数の「5」がかえります。
(runeの概念は今回ははしょります。)
文字列の比較
単純に文字列を比較するだけなら「==」でいけます。
var sa1 = "123漢字かなカナ" var sa2 = "123漢字かなカナ" var sb = "123漢字かなカナ" if sa1 == sa2 { fmt.Println("OK") } else { fmt.Println("NG") } if sa1 == sb { fmt.Println("OK") } else { fmt.Println("NG") }
全角と半角を区別して比較してます。
まあ、当たり前。
これを全角・半角を無視して比較したいときは、前に書いた「Fold」で変換してフォーマットをあわせてやればよさげです。
var sa1 = "123漢字かなカナ" var sb = "123漢字かなカナ" psa1 := width.Fold.String(sa1) psb := width.Fold.String(sb) if psa1 == psb { fmt.Println("OK2") } else { fmt.Println("NG2") }
こうすれば、結果は「OK2」になります。
stringsパッケージに「strings.EqualFold」というのがあって、なんとなくそれを使えば同じように比較できそうに思えますが、全角・半角まで考慮はしてくれません。
以下のように、半角の大文字・小文字の違いだけなら無視できます。
var a = "abcですよ" var b = "ABCですよ" if strings.EqualFold(a, b) { fmt.Println("OK3") } else { fmt.Println("NG3") }
とりあえず、今回はこのくらいですかね。
ではでは。