Я мог бы использовать несколько советов —
Я разбираю двоичный файл в php, если быть точным, это rom-файл Sega Genesis. В соответствии с таблицей, которую я составил, определенные байты соответствуют символам или управляют различными вещами с помощью текстового движка игры.
Существуют байты, которые используются как для символов, так и для байтов «контроллера», для разрывов строк, условий, цвета и множества других вещей, поэтому типичное предложение, вероятно, будет выглядеть так:
FC 03 E7 05 D3 42 79 20 64 6F 69 6E 67 20 73 6F 2C BC BE 08 79 6F 75 20 6A 75 73 74 20 61 63 71 75 69 72 65 64 BC BE 04 61 20 74 65 73 74 61 6D 65 6E 74 20 74 6F 20 79 6F 75 72 BC 73 74 61 74 75 73 20 61 73 20 61 20 77 61 72 72 69 6F 72 21 BD BC
который я могу перевести на:
<FC><03><E7><05><D3>By doing so,<NL><BE><08>you just acquired<NL><BE><04>a testament to your<NL>status as a warrior!<CURSOR>
Я хочу указать свойства для такой строки байта контроллера, такие как длина, и записать свои собственные значения в определенные позиции.
Увидеть,
байты, которые переводятся в символы (от 00 до 7F) или разрывы строк (BC), состоят только из одного байта, в то время как другие состоят из 2 (BE XX). Условия (FC) даже состоят из 5 байтов:
FC XX YY (где X и Y относятся к смещениям, которые мне нужно рассчитать, пока я соединяю свои переведенные строки)
Я хочу, чтобы мой анализатор распознал такие байты и позволил мне динамически писать XX YY.
Используя strtr, я могу заменить только «группы», например. когда я помещаю статическую байтовую строку в массив.
Как бы вы это сделали, сохранив синтаксический анализатор?
Спасибо!
Предполагая, что ваши шестнадцатеричные значения доступны в виде строки, вы можете использовать это регулярное выражение, чтобы проанализировать его, как вы упомянули. Если вы определили больше правил, кроме FC **** или BE **, вы можете напрямую добавить их в приведенное ниже регулярное выражение, чтобы они также были извлечены.
(?<fc>FC(\w\w){4})|(?<be>BE(\w\w))|(?<any>(\w\w))
Теперь используя именованные группы fc
, be
, any
легко определить набор результатов, используя массивы, такие как $matches['fc']
,
Regex Demo: https://regex101.com/r/kR9kdP/5
$re = '/(?<fc>FC(\w\w){4})|(?P<be>BE(\w\w))|(?P<any>(\w\w))/';
$str = 'FC03E705D3FC0006042842616D20626162612062';
preg_match_all($re, $str, $matches, PREG_PATTERN_ORDER, 0);
// Print the entire match result
print_r(array_filter($matches['fc'])); // Returns an array with all FC****
print_r(array_filter($matches['be'])); // Returns an array with all BE**
print_r(array_filter($matches['any'])); // Returns rest **
PHP Demo: http://ideone.com/qWUaob
Пример результатов:
Array
(
[0] => FC03E705D3
[1] => FC00060428
)
Array
(
[50] => BE08
[59] => BE04
[113] => BE08
[132] => BE04
)
Надеюсь это поможет!
Вы можете поместить шестнадцатеричные символы в регулярное выражение, используя \x##
, где ##
это шестнадцатеричный код для символа. Таким образом, вы можете соответствовать FC XX YY
с:
preg_match('/(?=\xfc).{4}/, $bytes, $match);
$match[0]
будет содержать 4 байта после FC
, Вы можете разбить их на пары с группами захвата:
preg_match('/(?=\xfc)(..)(..)/, $bytes, $match);
$match[1]
будет содержать XX
а также $match[2]
будет содержать YY
,