RegEx在已知良好值上失败


RegEx Fails on Known Good Value

我有一个regex,用于检测看似合理的Base64字符串。它在测试中工作https://regex101.com对于所有预期的测试值。

~^((?:[a-zA-Z0-9/+]{4})*(?:(?:[a-zA-Z0-9/+]{3}=)|(?:[a-zA-Z0-9/+]{2}==))?)$~

然而,当我在PHP中使用这种模式时,我发现一些值莫名其妙地失败了。

$tests = array(
    'MFpGQkVBJTNkJTNkfTxCUj4NCg0KICAgIDwvZm9udD4=',
    'MFpGRkVBJTNkJTNkfTxCUj4NCg0KICAgIDwvZm9udD4=',
    'MFpGSkVBJTNkJTNkfTxCUj4NCg0KICAgIDwvZm9udD4=',
);
foreach ($tests as $str) {
    $result = preg_match(
        '~^((?:[a-zA-Z0-9/+]{4})*(?:(?:[a-zA-Z0-9/+]{3}=)|(?:[a-zA-Z0-9/+]{2}==))?)$~i',
        preg_replace('~['s'R]~u', "", $str)
    );
    var_dump($result);
}

结果:

int(1)
int(0)
int(1)

问题:为什么第二个测试字符串的模式失败了?

问题出现在preg_replace调用中:

preg_replace('~['s'R]~u', "", $str)

字符类'R内部正在匹配并从数组中的第二个元素中删除文字R,从而导致preg_match失败。

更改为:

preg_replace('~'s|'R~u', "", $str)

由于's也将与'R匹配,您可以执行以下操作:

preg_replace('~'s+~u', "", $str)