如何将连续的十六进制字符串拆分为空格分隔的十六进制块,每个块包含 32 个连音?

问题描述 投票:0回答:4

我有一个相当长的十六进制字符串

Buffer.toString("hex")
,我想将其打印到日志文件中,每个字符串包含 32 个连音。

所以基本上是从

e01102020809020300800202020809020208095f520c8066054445472b44739621e0d003040401d21044454946583532463447444a4d010000d3104445472b445333374f53474b32010000d4104445472b44533337474b563033010000d503040401d6104445472b444342324354473031010000d7104445472b44504450535f5f5f5f0106009000

e0 11 02 02 08 09 02 03 00 80 02 02 02 08 09 02 02 08 09 5f 52 0c 80 66 05 44 45 47 2b 44 73 96
21 e0 d0 03 04 04 01 d2 10 44 45 49 46 58 35 32 46 34 47 44 4a 4d 01 00 00 d3 10 44 45 47 2b 44
53 33 37 4f 53 47 4b 32 01 00 00 d4 10 44 45 47 2b 44 53 33 37 47 4b 56 30 33 01 00 00 d5 03 04
04 01 d6 10 44 45 47 2b 44 43 42 32 43 54 47 30 31 01 00 00 d7 10 44 45 47 2b 44 50 44 50 53 5f
5f 5f 5f 01 06 00 90 00

我已经尝试过

hex.replace(/.{64}/g, "$1\n")
将十六进制字符串包裹在32个连音之后,但现在不知道如何在连音之间添加空格。 如果可能的话,我更愿意在一个正则表达式中做到这一点?

javascript regex hex hexdump
4个回答
3
投票

您实际上无法在 JavaScript 中的一个正则表达式中执行此操作,因为它不支持可变长度后向查找(一般情况下)、条件替换

\G
元序列等功能。您可以将字符串拆分为最多 64 个字符的块,然后将这些字符串拆分为最多 2 个字符的块,并用空格和换行符连接拆分:

const hex = 'e01102020809020300800202020809020208095f520c8066054445472b44739621e0d003040401d21044454946583532463447444a4d010000d3104445472b445333374f53474b32010000d4104445472b44533337474b563033010000d503040401d6104445472b444342324354473031010000d7104445472b44504450535f5f5f5f0106009000'

const out = hex
    .match(/(.{1,64})/g)
    .map(s => s.match(/.{1,2}/g).join(' '))
    .join('\n')

console.log(out)

注意,我在第二个正则表达式中使用了

{1,2}
,以防您的数据可能包含奇数个字符。如果不会,您可以简单地使用
.{2}
(或简化为
..
)。

您还可以定义一个替换函数,使用一个正则表达式将字符串拆分为可变的行长度:

const replacer = n => {
  let cnt = 0
  return (m) => m + ((++cnt % n) ? ' ' : '\n')
}

const hex = 'e01102020809020300800202020809020208095f520c8066054445472b44739621e0d003040401d21044454946583532463447444a4d010000d3104445472b445333374f53474b32010000d4104445472b44533337474b563033010000d503040401d6104445472b444342324354473031010000d7104445472b44504450535f5f5f5f0106009000'

let out = hex.replace(/../g, replacer(32))

console.log(out)

out = hex.replace(/../g, replacer(16))

console.log(out)

out = hex.replace(/../g, replacer(8))

console.log(out)


1
投票

要将十六进制字符串格式化为 32 个连音块,每个连音块在 JavaScript 中带有空格和换行符,您可以使用两步方法:

  1. 在每对字符之间添加空格。
  2. 每 32 对后插入一个换行符(96 个字符,包括空格)。

let hexString = "e01102020809020300800202020809020208095f520c8066054445472b44739621e0d003040401d21044454946583532463447444a4d010000d3104445472b445333374f53474b32010000d4104445472b44533337474b563033010000d503040401d6104445472b444342324354473031010000d7104445472b44504450535f5f5f5f0106009000";
    
hexString = hexString.replace(/(..)/g, "$1 ").trim(); 
    
hexString = hexString.replace(/(.{96})/g, "$1\n").trim(); 
    
 console.log(hexString);

这将为您提供所需的格式化字符串。


1
投票

您还可以在正则表达式引擎内进行循环:

const src = 'e01102020809020300800202020809020208095f520c8066054445472b44739621e0d003040401d21044454946583532463447444a4d010000d3104445472b445333374f53474b32010000d4104445472b44533337474b563033010000d503040401d6104445472b444342324354473031010000d7104445472b44504450535f5f5f5f0106009000';

function format(src) {
  let bytes = 0;
  return src.replace(/../g, byte => {
    if (bytes === 31) {
      bytes = 0;
      return `${byte}\n`;
    }
    bytes++;
    return `${byte} `;
  });
}

console.log(format(src));

(这可能会被代码打高尔夫球一点,但我想说清楚。)

它使用了字符串

.replace()
方法的特性,该方法允许将函数作为第二个参数传递。
format()
函数保留一个计数器并在换行时重置它。

正则表达式匹配将一遍又一遍地完成,但该正则表达式只会在每次迭代中“吃掉”两个字符,然后每次调用回调。它不会重新扫描整个源字符串。返回字符串是根据回调返回的值在正则表达式引擎内部构建的。


1
投票

您可以使用

\B
在连音之后断言非单词边界,以便仅在连音之间插入空格:

const hex = 'e01102020809020300800202020809020208095f520c8066054445472b44739621e0d003040401d21044454946583532463447444a4d010000d3104445472b445333374f53474b32010000d4104445472b44533337474b563033010000d503040401d6104445472b444342324354473031010000d7104445472b44504450535f5f5f5f0106009000';
console.log(hex.replace(/.{64}/g, '$&\n').replace(/..\B/g, '$& '))

© www.soinside.com 2019 - 2024. All rights reserved.