2011-07-16 2 views
0

Javaで正規表現を使用する際にいくつか問題があります。私はISOファイルを検索しようとしていて、そこにJPGイメージがあればそれを切り出します。JPGカービングのJava正規表現

Pattern imageRegex = Pattern.compile("\\x45\\x78\\x69\\x66"); //Exif regex 

これは正常に動作し、私はその後、EXIF情報を切り開く提出することができます:現時点では

は、私は、次の正規表現を使用して、JPG内EXIF情報を見つけると成功を抱えています。私は、この正規表現を使用する場合

しかし、:

Pattern imageRegex = Pattern.compile("\\xff\\xd8\\xff"); //JPG header regex 

Javaは任意のマッチを見つけることができません。 ISOファイル内にJPGが存在することを確認できます。

私は一度に200バイトのファイルをバイト配列に読み込み、それを正規表現になるように文字列に変換しています。

これはちょっと混乱しているように、これがなぜ起こっているのか誰にでも助言できますか?

また、Javaで正規表現を使用してJPGを彫刻するファイルの問題に近づくには、誰も助けてください。

アドバイスをいただければ幸いです。

答えて

0

私は一度にファイルの200バイトをバイト配列に読み込み、それを正規表現になるように文字列に変換しています。

おそらくすべてのJPEGヘッダーがN * 200の境界線にまたがって分割されていることがあります。

とにかく、これはバイナリデータを検索するにはかなり比例しない(非効率的な)方法です。ヘッダーを見つけるまで、input streamを通過してみませんか?

0

バイト配列を読み込んで文字列に変換している場合、文字列のエンコーディングの問題が原因で後方に噛み付いている可能性があります。

0x45 0x78 0x69 0x66 
E x i f 

が、JPEGヘッダではない:そうあなたが探しているEXIFパターンはすべてASCII互換であることを起こる

0xff 0xd8 0xff 

あなたはヤクブのアドバイスをfolowためにうまくやっだろうと正規表現をスキップします。

+0

感謝。 exifデータがすべての有効なASCII文字であるため、どのように一致しているのか理解しています。 私が理解しづらいのは、単純に一連のバイトを照合することなく、JPGヘッダーと一致させるためにバイト[]などを使用する方法です。 私はfileinputstream APIを見てきましたが、まだ少し混乱しています。 バイトをどのように一致させるかについて、より良いソリューションを提供できますか? 私は単に答えを私に渡すことを望んでいませんが、私はこれに新しいです、そして、私は急速にますます混乱しています。 – user848044

+0

最も簡単な方法は、0xff' 'を探しているバイト配列を通じてだけループするだろう おかげ - あなたがものを見つけたときには、それはそれに続く' 0xd8'と '0xff'が続いていますかどうかを確認します。このプロセスを最適化する方法(Boyer-Mooreアルゴリズムなど)がありますが、簡単なアプローチは初心者にとってはうまくいくでしょう。 – duskwuff

0

正規表現を使用してバイナリシーケンスを照合することはほとんどありません。バイナリデータとJavaの文字列の概念の違いをよく知っているのだろうか(Cとは対照的に)。

A JPEGファイルのバイナリデータ(バイトのシーケンスが)、あなたは文字列(文字のシーケンス)として、Javaでそれを持っている必要があり、パターンの正規表現で使用することです、彼らは根本的に異なるエンティティであり、いくつかの文字セットのエンコーディングを指定する必要があります。さらに、パターン内またはリテラル文字列としてリテラル\x45を指定すると、「バイナリ値0x45のバイト」を意味するわけではありません(これは意味をなさないでしょう。バイトを扱っていないためです)、 "ユニコードの文字ポイント番号0x45"となります。

通常の文字コードのエンコーディング(特にUTF-8とISO-8859-1およびその変形)では、 "ascii範囲"(127未満)のバイトシーケンスがそのバイト値とのコードポイント。しかし、他のエンコーディング(UTF-16など)や他の値(128-255の範囲)では、それは必要ではありません。特に、UTF-8の場合はそうではありません.ISO-8859-1ではこれが当てはまりますが、この「偶然性」には頼るべきではありません(これは偶然の場合です)。

あなたのシナリオでは、ISO-8859-1エンコーディングを指定すると、おそらくあなたが期待するものが得られると言えます。しかし、それでも悪いにおいがします。

演習:何このコードを印刷理解/予測しよう:答えを参照するには、以下のオーバー

public static void main(String[] args) throws Exception { 
    byte[] b = { 0x30, (byte) 0xb2 }; 
    String x = new String(b, "ISO-8859-1"); 
    System.out.println(x.matches(".*\\x30.*")); 
    System.out.println(x.matches(".*\\xb2.*")); 
    String x2 = new String(b, "UTF-8"); 
    System.out.println(x2.matches(".*\\x30.*")); 
    System.out.println(x2.matches(".*\\xb2.*")); 
} 

置き、マウスを。

の情報のため

真真真偽