RegEx因已知的良好价值而失败

时间:2015-03-18 19:58:16

标签: php 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)

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

1 个答案:

答案 0 :(得分:4)

问题出在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)