Использование регулярных выражений для сопоставления двоичных последовательностей редко уместно; Интересно, хорошо ли вы осведомлены о концептуальных различиях между двоичными данными и строками в Java (в отличие, скажем, от C).
Файл 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.*"));
}
Наведите указатель мыши внизу, чтобы увидеть ответ.