- 締切済み
(C#)1バイトの正規表現
下記のような正規表現による置換をほどこしました。 Buffer=Regex.Replace(Buffer,"^[\x00-\xff]{100}","",RegexOptions.Singleline); 文字列の先頭の100バイトを削除する正規表現ですが、うまく動作しません。 どうも文字コードに問題があるようなのですが、原因のわかる方いらっしゃいますか?
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- oldroot2005
- ベストアンサー率66% (68/103)
問題点、理解できました。 .NET では、1文字==2バイトですから、1バイトにマッチする正規表現というのはありえません。 また、バイナリデータを string に読み込むと、指定した encoding によっては変換されるため、ファイル中で 100 バイトだったデータが、string で 100 文字になるとは限りません。したがって、Regex.Replace や Substring でバイナリデータの部分を捨てることもできません。 結局のところ、いったん string に読み込んでしまったら、どうにもならない、ということです。ファイルから読み込む時点で、バイナリデータの部分をスキップするのが妥当な方法でしょう。以下は例です。 using System; using System.IO; using System.Text; using System.Text.RegularExpressions; class ReadData { static void Main() { char [] buf; FileStream fs = new FileStream("data.dat", FileMode.Open); Encoding enc = Encoding.GetEncoding("shift-jis"); BinaryReader br = new BinaryReader(fs, enc); br.BaseStream.Seek(100, SeekOrigin.Begin); // 100 バイトスキップ buf = br.ReadChars((int)(br.BaseStream.Length-br.BaseStream.Position)); br.Close(); string str = new string(buf); // string に変換する必要があれば Console.WriteLine(str); } }
- oldroot2005
- ベストアンサー率66% (68/103)
まず根本的な話なのですが、「先頭の100バイト」とはどのような意味でしょうか。.NET では文字コードは UNICODE ですから、とりあえずサロゲートペアを度外視すれば、1文字==2バイトです。したがって、馬鹿正直に解釈すれば、「先頭の100バイト」は「先頭の50文字」という意味になります。もしそうなら、 Regex.Replace(Buffer,"^[\u0000-\uffff]{50}","",RegexOptions.Singleline) あるいは、単純に Regex.Replace(Buffer,"^.{50}","",RegexOptions.Singleline) となります。しかし、わざわざ Regex を使わなくても、 Buffer.Substring(50) で目的は達せられます。 もし、Buffer の中身が Shift-JIS コードだと考え、いわゆる半角文字==1バイト、いわゆる全角文字==2バイトとして、「先頭100バイト」と言っておられるのなら、No.1 さんの方法で Shift-JIS に変換しなければなりません(Encoding に Shift-JIS が指定できるとしての話ですが)。 その場合、100バイト目に2バイト文字の1バイト目が来てしまったときの処理をしなければならないので、単純には行かないと思います。
補足
馬鹿正直に100バイトです。 説明し忘れましたが、バイナリファイル「っぽい」ファイルを開いていまして、Shift-jisの文字列の前に、正体不明のバイナリ値が100バイトあるのです。 というわけで、提示いただいた正規表現は使えません。 というより、正規表現では無理なのかな?
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
"^[\x00-\xff]{100}" は、マルチバイト文字列にはマッチしないようです。 #1さんのようにすればいいと思います。
- SpiralGalaxy
- ベストアンサー率39% (649/1653)
C#はやったことないんですが Javaだとこれでいきます。 String kotae = buffer.replaceFirst("^.{100}", ""); Javaは全部ユニコード操作なので1バイト文字、2バイト文字での操作の違いというのは無く、C#でその辺りが問題になるのなら、駄目かもしれません。
お礼
C#もUnicodeらしいのですが、何だかよくわかりませんね。
- osamuy
- ベストアンサー率42% (1231/2878)
本当に100バイトずつ削除したいなら、いったんGetByes()で、バイト配列に変換してから、操作してみては。
お礼
うーん それしかないのかな…。 できれば正規表現で何とかしたいのですが…。
お礼
確かにできそうにありませんね。 おとなしくバイト配列に読み込んで処理することにします。