• 締切済み

(C#)1バイトの正規表現

下記のような正規表現による置換をほどこしました。 Buffer=Regex.Replace(Buffer,"^[\x00-\xff]{100}","",RegexOptions.Singleline); 文字列の先頭の100バイトを削除する正規表現ですが、うまく動作しません。 どうも文字コードに問題があるようなのですが、原因のわかる方いらっしゃいますか?

みんなの回答

回答No.5

 問題点、理解できました。  .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); } }

randman
質問者

お礼

確かにできそうにありませんね。 おとなしくバイト配列に読み込んで処理することにします。

回答No.4

 まず根本的な話なのですが、「先頭の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バイト目が来てしまったときの処理をしなければならないので、単純には行かないと思います。

randman
質問者

補足

馬鹿正直に100バイトです。 説明し忘れましたが、バイナリファイル「っぽい」ファイルを開いていまして、Shift-jisの文字列の前に、正体不明のバイナリ値が100バイトあるのです。 というわけで、提示いただいた正規表現は使えません。 というより、正規表現では無理なのかな?

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.3

"^[\x00-\xff]{100}" は、マルチバイト文字列にはマッチしないようです。 #1さんのようにすればいいと思います。

回答No.2

C#はやったことないんですが Javaだとこれでいきます。 String kotae = buffer.replaceFirst("^.{100}", ""); Javaは全部ユニコード操作なので1バイト文字、2バイト文字での操作の違いというのは無く、C#でその辺りが問題になるのなら、駄目かもしれません。

randman
質問者

お礼

C#もUnicodeらしいのですが、何だかよくわかりませんね。

  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.1

本当に100バイトずつ削除したいなら、いったんGetByes()で、バイト配列に変換してから、操作してみては。

参考URL:
http://www.microsoft.com/japan/msdn/library/ja/cpref/html/frlrfsystemtextencodingclassgetbytestopic.asp
randman
質問者

お礼

うーん それしかないのかな…。 できれば正規表現で何とかしたいのですが…。

関連するQ&A