我一直在试图编写我需要的这个正则表达式。基本上,我有一个长字符串,其中包含两种不同类型的数据:

  • [a-f0-9] {32}
  • [a-zA-Z0-9 =] {x}

  • 问题是,x仅在特定实例中是常数:如果在一种情况下,它恰好是12,则对于该特定数据集它将是12,但是下次我运行正则表达式时,它可能需要是15或45例如。我在类型(2)的每段之间都有类型(1)的不可预测的数目。我的目标是“收获”所有类型(2)的数据。

    例如,我可以使用以下形式的字符串:
    [a-f0-9]{192}
    [a-zA-Z0-9=]{11}
    [a-f0-9]{96}
    [a-zA-Z0-9=]{11}
    [af-0-9]{160}
    [a-zA-Z0-9=]{11}
    

    (全部放在一起,没有界限)。我需要它返回由[a-zA-Z0-9 =]字符集的33个字符组成的字符串。事实数
    每个子串中的字符的个数在实例中是恒定的(在上面的例子中是11,但是很容易就是13),因为它包含较小的字符集,否则将无法知道其中一个字符串开始,另一端结束。

    我一直在努力使它工作近一个月,而且我几乎要拔掉头发了。我对正则表达式不是特别擅长...

    示例数据:
    3c21e03a10b9415fb3e1067ea75f8205
    c8dc9900a5089d31e01241c7a947ed7e
    d5f8cd6bb86ebef6d7d104c84ae6e8a7
    e23c99af9c9d6d0294d8b51094c39021
    4bb4af7e61760735ba17c29e8f542a66
    875da91e90863f1ddb7e149297fc59af
    cf5de951fb65d06d2927aab7b9b54830
    e2d935616a54c381c2f38db3731d5a37
    SGVsbG8gbXk
    6dd11d15c419ac219901f14bdd999f38
    0ad94e978ad624d15189f5230e5435a9
    2dc19fe95e583e7d593dd52ae7e68a6e
    465ffa6074a371a8958dad3ad271181a
    23310939b981b4e56f2ecee26f82ec60
    fe04bef49be47603d1278cc80673b226
    gbmFtZSBpcy
    3c21e03a10b9415fb3e1067ea75f8205
    c8dc9900a5089d31e01241c7a947ed7e
    d5f8cd6bb86ebef6d7d104c84ae6e8a7
    e23c99af9c9d6d0294d8b51094c39021
    BvbGl2ZXIga
    4bb4af7e61760735ba17c29e8f542a66
    875da91e90863f1ddb7e149297fc59af
    cf5de951fb65d06d2927aab7b9b54830
    e2d935616a54c381c2f38db3731d5a37
    G9vcmF5IQ==
    

    我想提取“SGVsbG8gbXkgbmFtZSBpcyBvbGl2ZXIgaG9vcmF5IQ ==“。

    最佳答案

    这是您的幸运日!该问题通常无法解决,但我相信以下内容几乎总是可以为现实生活中的典型数据提供正确的答案:

    <?php
    
    $s = '
    3c21e03a10b9415fb3e1067ea75f8205
    c8dc9900a5089d31e01241c7a947ed7e
    d5f8cd6bb86ebef6d7d104c84ae6e8a7
    e23c99af9c9d6d0294d8b51094c39021
    4bb4af7e61760735ba17c29e8f542a66
    875da91e90863f1ddb7e149297fc59af
    cf5de951fb65d06d2927aab7b9b54830
    e2d935616a54c381c2f38db3731d5a37
    SGVsbG8gbXk
    6dd11d15c419ac219901f14bdd999f38
    0ad94e978ad624d15189f5230e5435a9
    2dc19fe95e583e7d593dd52ae7e68a6e
    465ffa6074a371a8958dad3ad271181a
    23310939b981b4e56f2ecee26f82ec60
    fe04bef49be47603d1278cc80673b226
    gbmFtZSBpcy
    3c21e03a10b9415fb3e1067ea75f8205
    c8dc9900a5089d31e01241c7a947ed7e
    d5f8cd6bb86ebef6d7d104c84ae6e8a7
    e23c99af9c9d6d0294d8b51094c39021
    BvbGl2ZXIga
    4bb4af7e61760735ba17c29e8f542a66
    875da91e90863f1ddb7e149297fc59af
    cf5de951fb65d06d2927aab7b9b54830
    e2d935616a54c381c2f38db3731d5a37
    G9vcmF5IQ==
    ';
    $s = preg_replace('/\r?\n/', '', $s);
    
    for ($i = 1; $i < 20; ++$i) {
        $pattern = "/^(([a-f0-9]{32})+([a-zA-Z0-9=]{{$i}})?)+$/";
        if (preg_match($pattern, $s)) {
            $pattern = "/(?:[a-f0-9]{32})+([a-zA-Z0-9=]{{$i}})/";
            $matches = array();
            preg_match_all($pattern, $s, $matches);
            print_r(join('', $matches[1]));
            break;
        }
    }
    

    在这种情况下的输出:
    SGVsbG8gbXkgbmFtZSBpcyBvbGl2ZXIgaG9vcmF5IQ==
    

    我相信可以对代码进行改进,但是我敢肯定您很高兴得到一些有用的东西。我认为这类似于您在上文中描述的“火箭筒”方法,但是老实说,我认为没有更好的方法。还要注意,重要的是要先从小的猜测开始,以最大程度地减少错误匹配的机会。正则表达式中术语的顺序对于增加在多个选择可能的情况下正确选择的可能性也很重要(最难匹配的方法是首先尝试匹配,贪婪,然后在匹配失败时进行最简单的匹配)。

    07-25 22:36
    查看更多