文字を省略する際に、全角/半角を考慮する方法と、中間で省略する方法(Ruby)
【結論】
・文字を省略する際、全角/半角を考慮しないとレイアウトが崩れる場合がある。また末尾で省略すると、ファイル名なら拡張子が見えなくなるという問題が発生する。
・全角/半角を考慮する場合は、bytesizeメソッドを利用する
・中間で省略する場合は、文字を前半部と後半部に分けて結合する
【目次】
【本題】
文字の省略を柔軟に行いたい
前回文字を省略して表示する方法を投稿しましたが、これには欠点があります。
それは、文字を中間で省略できないという事と、文字の長さではなく数を基準に省略する位置を決めるので、同じ文字数で省略しても、全角/半角で最終的な長さが大きくズレてしまうという事です。
#文字を中間で省略できない str = "abcdefg" str.truncate(6) => "abc..."
#同じ文字数で省略しても、全角/半角で最終的な長さが大きくズレてしまう short = "abcdefghijklnmop" long = "あいうえおかきくけこさしすせそ" short.truncate(10) => "abcdefghij..." long.truncate(10) => "あいうえおかきくけこ..."
文字が末尾で省略されてしまうと、ファイル名を出力する場合は、拡張子が見えないという問題が発生します。
全角と半角で最終的な長さが異なると、意図せずレイアウトが崩れてしまう要因となり得ます。
この問題に対処する方法を、今回はまとめます。
文字を中間で省略する
今回の方法は、文字を前半部と後半部で分けて、間に「...」を挟んで結合するというやり方です。
str = "abcdefghijk" str_size = str.size split_point = 2 str[0, split_point] + '...'+ str[str_size-split_point, str_size] => "ab...jk"
この様にして、文字を中間で省略する事が可能です。
全角/半角を見分ける
Rubyには全角を見分けるメソッドはありませんが、文字のバイト数を調べるメソッドは存在します。
https://ref.xaio.jp/ruby/classes/string/bytesize
文字のバイト数は、半角で1バイト、全角で3バイトなので、この情報を基に識別します。
例えば、全角を半角の2倍として、文字数が半角10文字相当より多い場合は、前半・後半を2文字づつに分割して中間で省略する場合の、下記の様に行います。
def truncate_str(str) size = str.size byte = str.bytesize total_size = ((byte - size) / 2) + size if total_size > 10 split_point = 2 str[0..split_point-1] + '...' + str[(size - split_point)..size] else str end end short = "abcdefghij" long = "あいうえおかきくけこ" truncate_str(short) => "abcdefghij" truncate_str(long) => "あい...けこ"
これで全角と半角で長さに大きな差が開くことを防げます。
全て全角だった場合に合わせて、省略する文字数を調整すれば、レイアウトが崩れる事は無くなります。