ジュリアでユニコード文字列の一部だけをスライスする方法
概要
他のプログラム言語がそうであるように、ジュリアでは英語をASCIIコードaSCII Codeで書き、漢字、韓国語などをユニコードunicodeで書く。問題は、他の言語たちと違って、この文字列たちを扱うことがかなり厄介であることだけど、これは性能上の理由から意図されたものであるため1、不便でも我慢して使うしかない。
コード
julia> str1 = "English"
"English"
julia> str2 = "日本語"
"日本語"
julia> str3 = "한국어"
"한국어"
例えば、上のような文字列たちが与えられているとしよう。
julia> str1[2:end]
"nglish"
str1
の場合は何も特別なことがない英語の文字列で、ASCIIコードであるため、上のように普通の配列にアクセスするようにスライシングが可能である。
julia> str2[2:end]
ERROR: StringIndexError: invalid index [2], valid nearby indices [1]=>'日', [4]=>'本'
Stacktrace:
[1] string_index_err(s::String, i::Int64)
@ Base .\strings\string.jl:12
[2] getindex(s::String, r::UnitRange{Int64})
@ Base .\strings\string.jl:266
[3] top-level scope
@ c:\Users\rmsms\OneDrive\lab\population_dynamics\REPL.jl:6
しかし、str2
は漢字があるためにユニコードで書かれており、上のようにインデックスエラーを発生させる。エラーメッセージを見ると、2番目の文字のインデックスは2ではなく4であることが推測でき、実際に4からインデキシングをすると、意図された通りにスライシングされる。
julia> str2[4:end]
"本語"
これは以下のように韓国語にも同様に適用される。同じユニコードであるため、違う理由がない。
julia> str3[4:end]
"국어"
julia> str3[6]
ERROR: StringIndexError: invalid index [6], valid nearby indices [4]=>'국', [7]=>'어'
Stacktrace:
[1] string_index_err(s::String, i::Int64)
@ Base .\strings\string.jl:12
[2] getindex_continued(s::String, i::Int64, u::UInt32)
@ Base .\strings\string.jl:237
[3] getindex(s::String, i::Int64)
@ Base .\strings\string.jl:230
[4] top-level scope
@ c:\Users\rmsms\OneDrive\lab\population_dynamics\REPL.jl:9
julia> str3[7]
'어': Unicode U+C5B4 (category Lo: Letter, other)
トリック
julia> String(collect(str3)[2:3])
"국어"
まあまあ楽に使う方法としては、上のようにcollect()
で文字の配列に解いてスライシングし、また文字列にまとめる方法がある。
環境
- OS: Windows
- julia: v1.8.3