3

所以我一直在玩正则表达式,我的朋友挑战我写一个脚本来替换字符串中的所有十六进制。他给了我一个混合了不同字符的大文件,当然还有一些十六进制字符串。

每次出现的十六进制都以 开头\x,例如:\x55.

我认为这很容易,所以我在一些在线正则表达式测试器上尝试了这种模式:/\\x([a-fA-F0-9]{2})/

它工作得很好。

但是,当我将它放入一些 PHP 代码中时,它根本无法替换它。

任何人都可以帮助我朝着正确的方向前进吗?

这是我的代码:

$toDecode = file_get_contents('hex.txt');
$pattern = "/\\x(\w{2})/";
$replacement = 'OK!';

$decoded = preg_replace($pattern, $replacement, $toDecode);

$fh = fopen('haha.txt', 'w');
fwrite($fh, $decoded);
fclose($fh);
4

2 回答 2

5
<?php
  // grab the encoded file
  $toDecode = file_get_contents('hex.txt');

  // create a method to convert \x?? to it's character facsimile
  function escapedHexToHex($escaped)
  {
    // return 'OK!'; // what you're doing now
    return chr(hexdec($escaped[1]));
  }

  // use preg_replace_callback and hand-off the hex code for re-translation
  $decoded = preg_replace_callback('/\\\\x([a-f0-9]{2})/i','escapedHexToHex', $toDecode);

  // save result(s) back to a file
  file_put_contents('haha.txt', $decoded);

作为参考,preg_replace_callback。此外,请勿使用\w它实际上已翻译为[a-zA-Z0-9_]. 十六进制是 base-16,所以你想要[a-fA-F0-9](并且i标志使它不区分大小写)。

工作示例,减去文件部分。

于 2012-04-23T20:41:59.937 回答
2

您的问题是您没有转义 PHP 字符串中的反斜杠。它需要是:

$pattern = "/\\\\x(\\w{2})/";

...或者:

$pattern = '/\\x(\w{2})/';

...带单引号。 -这实际上遇到了同样的问题,需要完整的双转义序列

但是\w会匹配任何 perl 单词字符,而不仅仅是十六进制字符。我会改用字符类[a-fA-F0-9]

于 2012-04-23T20:38:44.537 回答