【问题标题】:Explode a string where the explode condition is bunch of specific characters分解一个字符串,其中分解条件是一堆特定字符
【发布时间】:2022-01-14 03:57:12
【问题描述】:

我正在寻找一种方法来分解字符串。例如,我有以下字符串:(我们不计算开头 - 0x

0xa9059xbb00000000000000000000000000fc7a5f48a1a1b3f48e7dcb1f23a1ea24199af4d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000004

这实际上是一个 ETH 交易输入。我需要将这个字符串分解成 3 部分。想象一串零实际上是一个空格 ,这些空格定义了字符串应该被分解的门。

我该怎么做?

【问题讨论】:

  • explode 使用分隔符拆分字符串。而你想要按索引的子字符串。
  • 普通的substr() 可能就可以了,因为我们有mb_substr() 用于多字节字符。
  • 您的 PHP 字符串是否包含实际的“原始”字节,或者您的字符串是否包含二进制内容的十六进制表示?
  • PHP 字符串是简单的字节数组,所以……你只是在看字符串切片。
  • 十六进制字符串中间有一个x。这是故意的吗?到目前为止,您尝试过什么?

标签: php explode


【解决方案1】:

如果您总是在相同的点(4 个字节(8 个十六进制数字)、32 个字节(64 个十六进制数字)、32 个字节(64 个十六进制数字))爆炸它们,您可以使用 substr()。

$input = "0xa9059xbb000000000000000000000000fc7a5f48a1a1b3f48e7dcb1f23a1ea24199af4d00000000000000000000000000000000000000000000000000000000000054368";
$first = substr($input,2,8);
$second = substr($input,10,64);
$third = substr($input,74,64);

print_r($first);
print "<br>";
print_r($second);
print "<br>";
print_r($third);
print "<br>";

这个输出:

a9059xbb
000000000000000000000000fc7a5f48a1a1b3f48e7dcb1f23a1ea24199af4d0
0000000000000000000000000000000000000000000000000000000000054368

【讨论】:

    【解决方案2】:

    preg_split()

    此函数使用正则表达式来拆分字符串。
    所以在这个例子中连续两个或多个0

    $arr = preg_split('/[0]{2,}/', $string);
    
    print_r($arr);
    echo PHP_EOL;
    

    这将输出以下内容:

    Array
    (
        [0] => a9059xbb
        [1] => fc7a5f48a1a1b3f48e7dcb1f23a1ea24199af4d
        [2] => 54368
    )
    

    请注意,如果消息本身包含00,您将遇到问题。假设它被用作“字符串结尾”的空字节,但这不会发生。

    preg_match()

    这是一个使用正则表达式的例子。您可以在任意点拆分。

    $string = 'a9059xbb000000000000000000000000fc7a5f48a1a1b3f48e7dcb1f23a1ea24199af4d00000000000000000000000000000000000000000000000000000000000054368';
    
    print_r($string);
    echo PHP_EOL;
    
    $res = preg_match('/(.{4})(.{32})(.{32})/', $string, $matches);
    
    print_r($matches);
    echo PHP_EOL;
    

    这个输出:

    a9059xbb000000000000000000000000fc7a5f48a1a1b3f48e7dcb1f23a1ea24199af4d00000000000000000000000000000000000000000000000000000000000054368
    Array
    (
        [0] => a9059xbb000000000000000000000000fc7a5f48a1a1b3f48e7dcb1f23a1ea24199a
        [1] => a905
        [2] => 9xbb000000000000000000000000fc7a
        [3] => 5f48a1a1b3f48e7dcb1f23a1ea24199a
    )
    

    如您所见,/(.{4})(.{32})(.{32})/ 将找到 4 个字节,然后是 32,然后又是 32。捕获组是使用 () 围绕您想要查找的内容创建的。它们出现在$matches 数组中(0 始终是找到的整个字符串)。

    如果你想忽略某些部分,你也可以表达出来:

    /(.{4})9x(.{32}).{4}(.{32})/
    

    这会改变找到的字​​符串:

    Array
    (
        [0] => a9059xbb000000000000000000000000fc7a5f48a1a1b3f48e7dcb1f23a1ea24199af4d000
        [1] => a905
        [2] => bb000000000000000000000000fc7a5f
        [3] => a1b3f48e7dcb1f23a1ea24199af4d000
    )
    

    链接

    上述函数的 PHP 文档:
    https://www.php.net/manual/en/function.preg-split.php
    https://www.php.net/manual/en/book.pcre.php

    使用此演示试玩第二个正则表达式:
    https://regex101.com/r/pfZtH8/1

    【讨论】:

    • 这是一个很好的解释,但我不确定这是否是我真正想要的。我会尽量用最简单的方式来解释它——想象一下,一串零实际上是一个空格 ` `,这些空格定义了字符串应该被分解的门。
    • 好的,我将添加到答案中,也可以这样做。请牢记这一点,更新您的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-21
    • 2012-05-21
    • 1970-01-01
    相关资源
    最近更新 更多