如何在PHP中使用RegEx替换所有十六进制?

时间:2022-03-06 21:03:50

So I've been toying around with Regular Expressions, and my friend challenged me to write a script that replaced all hex within a string. He gave me a large file mixed with different characters and, of course, some hex strings.

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

Each occurrence of hex is preceded with \x, so for example: \x55.

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

I thought it'd be pretty easy, so I tried out this pattern on some online regex tester: /\\x([a-fA-F0-9]{2})/

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

It worked perfectly.

它工作得很好。

However, when I throw it into some PHP code, it fails to replace it at all.

但是,当我把它扔进一些PHP代码时,它根本无法替换它。

Can anyone give me a nudge into the right direction of where I'm going wrong?

任何人都可以给我一个正确的方向,我错了吗?

Here's my code:

这是我的代码:

$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);

2 个解决方案

#1


2  

Your problem is that you have not escaped your backslashes in the PHP string. It needs to be:

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

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

...or:

...要么:

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

...with single quotes. - This actually suffers the same problem and requires the full double-escaped sequence

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

But \w will match any perl word character, which is not just hex characters. I would use the character class [a-fA-F0-9] instead.

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

#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);

For reference, preg_replace_callback. Also, don't use \w as it's actually translated to [a-zA-Z0-9_]. Hex is base-16, so you want [a-fA-F0-9] (and the i flag makes it case-insensitive).

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

Working example, minus the file part.

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

#1


2  

Your problem is that you have not escaped your backslashes in the PHP string. It needs to be:

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

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

...or:

...要么:

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

...with single quotes. - This actually suffers the same problem and requires the full double-escaped sequence

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

But \w will match any perl word character, which is not just hex characters. I would use the character class [a-fA-F0-9] instead.

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

#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);

For reference, preg_replace_callback. Also, don't use \w as it's actually translated to [a-zA-Z0-9_]. Hex is base-16, so you want [a-fA-F0-9] (and the i flag makes it case-insensitive).

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

Working example, minus the file part.

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