UTF-8 マルチバイト文字列を全角 n 文字(半角 n*2 文字)の固定長で改行させたい。
対象文字列あいうえおかきくけこさしすせそたちつてと 123456789012345678901234567890
↓
n=6で改行あいうえおか きくけこさし すせそたちつ てと 123456789012 345678901234 567890
等幅フォントでない限り、全角 1 文字 == 半角 2 文字
の文字幅にならないのは当然として、それでも CLI アプリやコマンドのヘルプ表示など、なるべく等幅(1 行が固定長)になるように折り返したいのです。
つまり Golang の WordWrap
がしたい。
しかし「"golang" 文字列 固定幅 改行」でググっても、なかなかヒットしなかったり、ルーンをゴニョゴニョしろとは言うもの具体的なものがなかったので、自分のググラビリティとして。
TL; DR (今北産業)
-
github.com/mattn/go-runewidth
パッケージのrunewidth
を使う。go-runewidth
は @mattn さんによる awesome-go なパッケージです。 -
runewidth.Wrap(s string, w int) string
メソッドで文字列s
をw
文字幅で改行した文字列が取得できる。 - 全角 3 文字の場合は
result := runewidth.Wrap(myString, 3 * 2)
と 2 倍にする。
TS; DR
sample.go
package main
import (
"fmt"
"strings"
"github.com/mattn/go-runewidth"
)
// WrapZenkakuString は文字列を固定幅で折り返します。幅の指定(width)は全角文字数を指定します。
// 半角文字は、その倍の文字数で折り返されます。主にヘルプ表示などに使われ、フォントによっては必ずし
// も固定幅になるとは限りません。
func WrapZenkakuStringSample(input string, width int) string {
replacer := strings.NewReplacer(
"\n", "",
"\r", "", // Windows
"。", "。\n",
)
replaced := replacer.Replace(input)
return runewidth.Wrap(replaced, width*2)
}
func main() {
var msgHelp string = `
これはサンプルのヘルプです。
アイウエオかきくけこサシスセソたちつ
てとナニヌネコ。`
fmt.Println(WrapZenkakuString(msgHelp, 6))
}
実行結果
$ go run .
これはサンプ
ルのヘルプで
す。
アイウエオか
きくけこサシ
スセソたちつ
てとナニヌネ
コ。
- オンラインで動作をみる @ Go Playground
- オンラインでテストをみる @ Go Playground
参考文献
- Text Processing | Awesome-go(golangのライブラリリスト)のスター数まとめ-全部編(2018/10/9版) @ Qiita
- awesome-go @ GitHub
- Goでマルチバイトが混在した文字列を文字幅でtruncateする @ Qiita
- コメント | Golang で指定した幅で文字列を丸める方法 @ Qiita
関連文献
-
github.com/mattn/go-runewidth
- リポジトリ: https://github.com/mattn/go-runewidth @ GitHub
- API ドキュメント: https://pkg.go.dev/github.com/mattn/go-runewidth @ pkg.go.dev
- ライセンス: MIT