解析 PHP 中二进制文件的字节并将组转换为占位符

Parsing bytes of a binary file in PHP and translate groups into a placeholder

我可以使用一些建议 - 我正在解析 php 中的一个二进制文件,具体来说,它是一个 Sega Genesis rom 文件。根据我所做的table,某些字节对应于游戏的文本引擎中的字符或控制不同的东西。

有字节,用于字符和 "controller" 字节,用于换行符、条件、颜色和一堆其他东西,所以一个典型的句子可能看起来像这样:

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 734 6 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 我只能替换 "groups" 例如当我将静态字节串放入数组时。

在保持解析器灵活性的同时,您将如何做到这一点? 谢谢!

您可以使用 \x## 将十六进制字符放入正则表达式中,其中 ## 是该字符的十六进制代码。所以你可以匹配 FC XX YY 与:

preg_match('/(?=\xfc).{4}/, $bytes, $match);

$match[0] 将包含 FC 之后的 4 个字节。您可以使用捕获组将它们分成两对:

preg_match('/(?=\xfc)(..)(..)/, $bytes, $match);

$match[1] 将包含 XX$match[2] 将包含 YY.

假设您的十六进制值可用作字符串,您可以使用此正则表达式来解析它,就像您提到的那样。如果您识别出 FC**** 或 BE** 以外的更多规则,那么您可以直接将它们添加到下面的正则表达式中,以便它们也被提取。

(?<fc>FC(\w\w){4})|(?<be>BE(\w\w))|(?<any>(\w\w))

现在使用命名组 fcbeany 以使用 $matches['fc'].

等数组轻松识别结果集

正则表达式演示: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 演示:http://ideone.com/qWUaob

示例结果:

Array
(
    [0] => FC03E705D3
    [1] => FC00060428
)
Array
(
    [50] => BE08
    [59] => BE04
    [113] => BE08
    [132] => BE04
)

希望对您有所帮助!