none
全角文字の何バイト目 RRS feed

すべての返信

  • Shift_JIS の話をしていますか?

    Visual C# のフォーラムで質問していると言うことは違うのかな?

    それを判定して何をしようとしているか、目的を書いていただけませんか?

    2016年9月3日 9:59
  • 補足で、

    C#における文字列(System.Stringクラス)はUTF-16エンコーディングです。偶数バイトが1バイト目で奇数バイトが2バイト目です。まぁ3とか4とかもありますが…。

    質問者さんの言う「文字列」「全角文字」「半角文字」が何を指しているのかを明確にする必要があります。

    • 回答の候補に設定 佐祐理 2016年9月5日 4:16
    2016年9月3日 11:54
  • Visual C# のフォーラムで質問していると言うことは、Shift_JIS の話ではなくて、多分、C# の文字列(String オブジェクト)のことを言っているのだろうと想像して・・・

    > 文字列のnバイト目が、半角文字か、全角文字の1バイト目か、2バイト目を判断する方法はないでしょうか。

    C# の String オブジェクトは Char 構造体のシーケンシャルコレクションです(「nバイト目」とか「半角文字」とか「全角文字」という概念はないです)。詳しい説明は以下の記事を見てください。

    Char 構造体
    https://msdn.microsoft.com/ja-jp/library/system.char(v=vs.100).aspx

    なので、String オブジェクトの中の当該 Char 構造体の 16 ビット値を調べることで文字の種類を判定することができます。

    質問者さんの言う「半角文字」「全角文字」というのは何だか分かりませんが、例えば、もし、Shift_JIS の 1 バイト文字のことを「半角文字」と言っているのであれば、String オブジェクトの当該 Char の 16 ビット値が、Shift_JIS の 1 バイト文字の UTF-16 コードの範囲内に含まれれば「半角文字」であると判定できます。


    Char 構造体のメンバーには文字が特定の Unicode カテゴリ (数字、アルファベット、区切り記号、制御文字など) に属しているかどうかを確認するメソッドも用意されています。

    質問者さんの言う「半角文字」が、例えばアルファベット文字または 10 進数の数字でよければ、Char.IsLetterOrDigit メソッドを使って簡単に判定できます。(訂正:なちゃさんの指摘の通り Char.IsLetterOrDigit ではダメでした。別途、案を書いておきます)



    2016年9月4日 4:24
  • 質問者さんの言う「半角文字」が、例えばアルファベット文字または 10 進数の数字でよければ、Char.IsLetterOrDigit メソッドを使って簡単に判定できます。

    いやこれはできないでしょう。

    いわゆる全角半角関係なくTrueです。

    というか漢数字ですらTrueだったような…

    ひらがなも漢字もレターですね確か…

    • 編集済み なちゃ 2016年9月4日 18:03
    2016年9月4日 18:00
  • 他所様の書かれたブログですが
    http://d.hatena.ne.jp/ku__ra__ge/20101021/p6
    みたいなことをすれば判断できるかなと思います。
    ただし、この例だとSHIFT-JISとしているように、文字コードはなんであるか、
    全角文字、半角文字とはなんであるか、ということは限定して考えないと
    いけないのはみなさんの仰るとおりです。

    2016年9月5日 1:15
  • > いやこれはできないでしょう。
    > いわゆる全角半角関係なくTrueです。
    > というか漢数字ですらTrueだったような…
    > ひらがなも漢字もレターですね確か…

    そうですね。検証してみましたが、例えば、

    String unicodeString = "あ𠀋a(4)アアA(4)";

    で IsLetterOrDigit が ture になるのは .NET 3.5 でも .NET 4 でも同じで、以下の文字でした:

    あa4アアA4

    上の回答は訂正しておきます。


    #言い訳ですが、.NET 3.5 の説明 "Unicode 文字がアルファベット文字または 10 進数の数字かどうかを示します" を頭から信じてました。

    #current version の説明では "指定した文字列の指定位置にある文字が文字または 10 進数の数字かどうかを示します" になってました。'(' とか '(' とか '𠀋'(サロゲート)はここで言う「文字」には含まれないようです。

    2016年9月5日 1:51
  • 返事が遅くなりましてすみません。

    Shift_JIS で考えています。全角は漢字、半角はASCII文字と考えています。

    目的は、郵便のカスタマーバーコードの住所の処理で、文字列の途中から、左側に向かって1バイトずつ見ていき、全角数字の部分だけを取り出し、違う文字に変換するためです。


    2016年9月5日 2:37
  • Shift_JIS で考えています。全角は漢字、半角はASCII文字と考えています。

    文字列は「3丁目45番地1号」のような文字列です。

    2016年9月5日 2:39
  • このブログを読んでみます。

    2016年9月5日 2:44
  • 上の私のレスで書いた:

    > 質問者さんの言う「半角文字」が、例えばアルファベット文字または 10 進数の数字で
    > よければ、Char.IsLetterOrDigit メソッドを使って簡単に判定できます。

    が間違っていましたので訂正して別の案を書いておきます。

    他の Char 構造体のメンバーメソッドを探してみましたが、「アルファベット文字または 10 進数の数字」を判定するのに適当なものはなさそうです。

    なので、「アルファベット文字または 10 進数の数字」の UTF-16 コードを調べて、それと一致する場合 true を、一致しない場合は false を返すメソッドを自作するのがよさそうです。

    例えば、「アルファベット文字または 10 進数の数字」を ASCII 文字の 0-9, A-Z, a-z ということにするなら、それらの UTF-16 コードは以下の通りですので、

    以下のようなメソッドを自作して判定することができます。

    public static bool IsAlphaOrDigit(char ch)
    {
        if ((0x0030 <= ch && ch <= 0x0039) ||   // 0 ~ 9
            (0x0041 <= ch && ch <= 0x005a) ||   // A ~ Z
            (0x0061 <= ch && ch <= 0x007a))     // a ~ z
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    Shift_JIS の 1 バイト文字なら以下のようなメソッドを自作して判定できると思います。

    public static bool IsHankaku(char ch)
    {
        if ((0x0020 <= ch && ch <= 0x007e) ||   // 0x20~0x7e の ASCII文字
            (0xff61 <= ch && ch <= 0xff9f))     // 0xa1~0xdf の半角カタカナ
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    2016年9月5日 2:45
  • 文字列「3丁目四五番地1号」を、「3丁目45番地1号」のように変換したい。

    丁目」や「番地」の左に漢数字がある場合は、半角に変換したい。

    2016年9月5日 2:48
  • レスが前後してしまいました。

    > 目的は、郵便のカスタマーバーコードの住所の処理で、文字列の途中から、左側に向かって
    > 1バイトずつ見ていき、全角数字の部分だけを取り出し、違う文字に変換するためです。

    それですと正規表現を使って置き換えた方がいいかもしれません。

    その方法ですが、以下の記事は参考になりませんか?

    全角数字を半角に変換
    http://surferonwww.info/BlogEngine/post/2016/01/15/convert-numeric-zenkaku-character-to-hankaku.aspx

    2016年9月5日 2:55
  • 上記サイトを読んでみます。

    2016年9月5日 3:07
  • 文字列「3丁目四五番地1号」を、「3丁目45番地1号」のように変換したい。

    丁目」や「番地」の左に漢数字がある場合は、半角に変換したい。

    他の説明にはShift_JIS等ありますが、この質問・目的には「Shift_JIS」も「バイト」も登場しません。

    単に'一'→'1'、'二'→'2'の変換がしたいだけであれば正規表現で十分です。

    static string Half(string input) {
        var map = new Dictionary<char, char> {
            { '〇', '0' },
            { '一', '1' },
            { '二', '2' },
            { '三', '3' },
            { '四', '4' },
            { '五', '5' },
            { '六', '6' },
            { '七', '7' },
            { '八', '8' },
            { '九', '9' },
        };
        return Regex.Replace(input, "[〇一二三四五六七八九]+(?=丁目|番地)", m => new String(m.Groups[0].Value.Select(c => map[c]).ToArray()));
    }
    static void Main(string[] args) {
        var address = "3丁目四五番地1号";
        Console.WriteLine("{0} => {1}", address, Half(address));
    }

    # '十'とかをどうするかは言及されていませんね。

    2016年9月5日 3:11
  • 丁目」や「番地」等の、特定の文字の左に漢数字がある場合、半角に変換したい。

    ということなので、「四日市市二五丁目」を「4日市市25丁目」と変換するのはNGです。

    「四日市市」を「4日市市」と変換するのはNG。

    丁目」が有ったら、左方向に探していって、「漢数字」の「二五」だけ「25」と変換したい。



    2016年9月5日 3:17
  • 正規表現を勉強してみませんか?

    以下の記事はタイトルが「ASP.NET の」となっていますが、一部(「ASP.NET での検証」のセクション)を除いては一般的に当てはまることが分かりやすく書いてあり、基本的な正規表現の知識を得るには適切だと思います。

    ASP.NET の正規表現
    https://msdn.microsoft.com/ja-jp/library/ms972966.aspx

    正規表現の基本的なところを勉強して知識をつけて、上のレスをもう一度読んでみて、自分の要件に合わせてどのように書き換えたら良いかを検討して、分からない点を質問するようにした方が、多分解決が早いと思います。

    2016年9月5日 3:34
  • 追記、

    「四百参十弐番地」は、「432番地」と変換したい。

    「百」「十」の文字は除いて。

    「参」は「弐」のような漢数字もあります。

    2016年9月5日 3:35
  • そのようにやりたいことを小出しされてはついていけません。

    自分の手には負えそうもないので撤退します。お役に立てずすみませんでしたが、他の方の回等をお待ちください。

    2016年9月5日 3:41
  • 小出しの件、すみませんでした。

    正規表現は勉強してみます。

    下記が目的に合っていそうなので、検討してみます。

    http://shiganaisenotes.blogspot.jp/2011/11/blog-post.html

    2016年9月5日 3:45
  • C#ではなくてVBですが、以下のサイトは参考になりますでしょうか?

    http://shiganaisenotes.blogspot.jp/2011/11/blog-post.html

    2016年9月5日 3:46
  • 別にフォーラムで質問しなくても質問者さんの希望されるようにプログラムを書けばいいです。

    フォーラムは希望に応える場でなく質問に答える場です。質問文にないことは答えようがありません。もし質問したいのであればまずは質問文を明確にする必要があります。

    2016年9月5日 4:15
  • 承知いたしました。

    2016年9月5日 4:44
  • > 「四日市市二五丁目」を「4日市市25丁目」と変換するのはNG
    でしたら、変換するべき文字列としてはいけない文字列を分割すればよいと思います。

    > 「丁目」が有ったら、左方向に探していって、「漢数字」の「二五」だけ「25」と変換したい。
    と書かれているので、投稿者様の中で、地名と丁目切り分け方法は考えられているのですよね?
    私には「新一一丁目」(しんいちいっちょうめ)のような町名だった場合にどのように分割すればよいか頭を抱えてしまいますが。

    > 「四百参十弐番地」は、「432番地」と変換したい。
    いろいろ条件がありそうですので、ご自身で変換テーブルを用意されればよいかと思います。

    > 「百」「十」の文字は除いて。
    「百一丁目」などのケースに対応するために、文字を除くのではなく、四 * 百と扱うべきです。

    佐祐理さんの仰られている通り、質問に答える場ですので
    やりたいことに対して、何を聞きたいのか明確にされたほうがよいかと思います。

    2016年9月5日 7:01
  • 承知いたしました。

    今後は、質問内容を整理してから、質問するようにいたします。

    今回の質問は、一旦締めたいと思います。

    2016年9月5日 14:57
  • http://www.post.japanpost.jp/zipcode/zipmanual/p17.html
    これ?
    郵便番号を決める情報が取れれば、それを削除した後の文字列は、数字にしても…あかんか。
    「第三ビル」は、抜き出したらあかんな。
    「番地」も注意。うちの実家は「◯番△号」。「番地」だと引っかからない。

    Jitta@わんくま同盟

    2016年9月6日 23:34