固定長文字列より指定位置の文字を取得 への返答
投稿で使用できる特殊コードの説明。(別タブで開きます。)
以下の返答は逆順(新しい順)に並んでいます。
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2020/7/29 09:33:59
> もし、51バイト目が必ず全角文字の前半部、または半角文字である、
> (同様に、60バイト目が必ず全角文字の後半部、または半角文字である)
> という前提があれば、るきお様の方法でも問題ないように思えるのですが、
> 如何でしょうか?
文字の区切り位置が明確になっているのであれば、
バイト位置固定での切り出しで問題ありません。
> (同様に、60バイト目が必ず全角文字の後半部、または半角文字である)
> という前提があれば、るきお様の方法でも問題ないように思えるのですが、
> 如何でしょうか?
文字の区切り位置が明確になっているのであれば、
バイト位置固定での切り出しで問題ありません。
投稿者 JETT  (社会人)
投稿日時
2020/7/29 09:17:57
皆様、回答ありがとうございました。
ところで、 魔界の仮面弁士様ご指摘の件ですが、
>> Skip(50).Take(10)
> UTF-8 とは異なり、Shift_JIS は文字列の途中からだと、
>それが全角文字の前半部なのか後半部なのかを調べられないので、
>バイナリに対して、この方法で切り出すのは危険だと思います。
もし、51バイト目が必ず全角文字の前半部、または半角文字である、
(同様に、60バイト目が必ず全角文字の後半部、または半角文字である)
という前提があれば、るきお様の方法でも問題ないように思えるのですが、
如何でしょうか?
ところで、 魔界の仮面弁士様ご指摘の件ですが、
>> Skip(50).Take(10)
> UTF-8 とは異なり、Shift_JIS は文字列の途中からだと、
>それが全角文字の前半部なのか後半部なのかを調べられないので、
>バイナリに対して、この方法で切り出すのは危険だと思います。
もし、51バイト目が必ず全角文字の前半部、または半角文字である、
(同様に、60バイト目が必ず全角文字の後半部、または半角文字である)
という前提があれば、るきお様の方法でも問題ないように思えるのですが、
如何でしょうか?
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2020/7/28 16:47:35
> Skip(50).Take(10)
UTF-8 とは異なり、Shift_JIS は文字列の途中からだと、
それが全角文字の前半部なのか後半部なのかを調べられないので、
バイナリに対して、この方法で切り出すのは危険だと思います。
たとえば、51 バイト目が「全角文字の後半部」だった場合に、
それを誤って「全角文字の前半部」として扱われる可能性がありえますが、
その場合先頭文字だけでなく、そのあとに続く文字も化けてしまう恐れがあります。
【区切り位置を誤認しやすい文字列の例】
面倒でも、Shift_JIS 文字列の先頭から、文字数(Char あるいは Rune 単位)で
一文字ずつ拾い出していくなどして、半角なら +1、全角なら +2 として
カウントしていく方が良いかも知れません。
UTF-8 とは異なり、Shift_JIS は文字列の途中からだと、
それが全角文字の前半部なのか後半部なのかを調べられないので、
バイナリに対して、この方法で切り出すのは危険だと思います。
たとえば、51 バイト目が「全角文字の後半部」だった場合に、
それを誤って「全角文字の前半部」として扱われる可能性がありえますが、
その場合先頭文字だけでなく、そのあとに続く文字も化けてしまう恐れがあります。
【区切り位置を誤認しやすい文字列の例】
"=" は Shift_JIS で 0x8181
"≠" は Shift_JIS で 0x8182
"a" は Shift_JIS で 0x8281
"b" は Shift_JIS で 0x8282
"≠" は Shift_JIS で 0x8182
"a" は Shift_JIS で 0x8281
"b" は Shift_JIS で 0x8282
面倒でも、Shift_JIS 文字列の先頭から、文字数(Char あるいは Rune 単位)で
一文字ずつ拾い出していくなどして、半角なら +1、全角なら +2 として
カウントしていく方が良いかも知れません。
投稿者 るきお  (社会人)
投稿日時
2020/7/28 11:43:48
ShiftJISの文字コードの配列に変換して、51バイト目から60バイト目を抜き出して、再びShiftJISとして文字列に変換するという方法が素直だと思います。
※.NET Core向けのコードも入れていますが、動作確認はしていません。
#If NETCOREAPP Then
'.NET Core/.NET 5以降の場合
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance)
#End If
Dim value As String = "あああああ AAAAいいいいいいいいいいいいいい 1111111111BBBBBBBBBB.txt"
Dim valurCharCodes As Byte() = System.Text.Encoding.GetEncoding("shift_jis").GetBytes(value)
Dim targetCharCodes = valurCharCodes.Skip(50).Take(10)
Dim result As String = System.Text.Encoding.GetEncoding("shift_jis").GetString(targetCharCodes.ToArray)
※.NET Core向けのコードも入れていますが、動作確認はしていません。
投稿者 JETT  (社会人)
投稿日時
2020/7/28 11:06:17
別のプログラムで生成されるファイルが、以下のようなファイル名であるとします。
"あああああ AAAAいいいいいいいいいいいいいい 1111111111BBBBBBBBBB.txt"
いわゆる固定長?というのでしょうか、全角を2バイト・半角を1バイトとした書式で、
指定桁数に足りない箇所は半角スペースで右埋めされています。
また、対象文字はすべてShift_JISで表現可能な文字であるとします。
例えば、このファイル名の51バイト目から60バイト目(上でいう所の"1111111111"の部分)を
Stringとして取得するにはどういった方法があるでしょうか?
"あああああ AAAAいいいいいいいいいいいいいい 1111111111BBBBBBBBBB.txt"
いわゆる固定長?というのでしょうか、全角を2バイト・半角を1バイトとした書式で、
指定桁数に足りない箇所は半角スペースで右埋めされています。
また、対象文字はすべてShift_JISで表現可能な文字であるとします。
例えば、このファイル名の51バイト目から60バイト目(上でいう所の"1111111111"の部分)を
Stringとして取得するにはどういった方法があるでしょうか?
これで解決しました。