2011-07-16 51 views
0

我在Java中使用正則表達式時遇到了一些問題。我試圖通過一個ISO文件進行搜索,並且如果有任何JPG文件,就可以分割出任何JPG文件。關於JPG雕刻的Java正則表達式

目前,我在用JPG內定位EXIF信息,使用下面的正則表達式成功:

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

這工作得很好,然後我可以將文件能開出的EXIF信息。

但是,如果我用這個正則表達式:

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

的Java未能找到任何匹配。我可以確認ISO文件中有JPG文件。

我正在讀200字節的文件在一個字節數組,然後將其轉換爲一個字符串是正則表達式。

任何人都可以建議爲什麼會發生這種情況,因爲它相當混亂。

或者任何人都可以建議一個更好的方法來解決在Java中使用正則表達式來處理JPG文件的問題嗎?

任何意見將不勝感激。

回答

0

我正在讀取200個字節的文件,每次讀入一個字節數組,然後將其轉換爲一個字符串以regex'd。

也許所有的JPEG標題都在N * 200邊界上分開。

無論如何,這是一種非常規(低效)的搜索二進制數據的方式。爲什麼不直接通過input stream直到找到標題?

0

如果你正在閱讀一個字節數組並將它轉換爲一個字符串,那麼字符串編碼問題有可能在後面咬你。恰巧,你要尋找的EXIF模式是所有的ASCII兼容:

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

但JPEG頭是不是:

0xff 0xd8 0xff 

你會做好folow中的Jakub的建議,跳過正則表達式。

+0

感謝您的信息。 我明白現在如何匹配exif數據,因爲它是所有有效的ascii字符。 我無法理解的是如何使用一個字節[]或類似的匹配一個JPG頭,而不是簡單地匹配一系列的字節。 我看了一下fileinputstream API,但我仍然有點困惑。 你可以提供一個更好的解決方案如何匹配字節? 我不是在找你,只是給我答案,但我是新來的,我越來越快越來越困惑。 謝謝 – user848044

+0

最簡單的方法就是循環尋找0xff的字節數組 - 當你找到一個時,檢查它是否後面跟着0xd8和0xff。有很多方法可以優化這個過程(比如Boyer-Moore算法),但簡單的方法對於初學者來說可以很好地工作。 – duskwuff

0

使用正則表達式匹配二進制序列很少適用;我想知道你是否清楚Java中二進制數據和字符串之間的概念差異(而不是C)。

JPEG文件是二進制數據(的字節序列),在模式正則表達式來使用,你必須有它在Java作爲一個字符串(的字符序列),它們是完全不同的實體,並且要從一個轉換到另一個,必須指定一些字符集編碼。此外,當你在一個模式中指定文字\x45或者指定一個文字字符串時,你的意思不是(像你認爲的那樣)「二進制值爲0x45的字節」(這是沒有意義的,因爲我們沒有處理字節)但是,「Unicode中的字符點號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.*")); 
} 

將鼠標放在下面來看看答案。

真真真假