【问题标题】:RegEx Fails on Known Good Value正则表达式已知物有所值失败
【发布时间】:2015-05-21 19:08:28
【问题描述】:

我有一个正则表达式,旨在检测合理的 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)

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

【问题讨论】:

  • 也许你不需要 RegEx :) stackoverflow.com/questions/2556345/… 有一个很好的答案(第二个答案)
  • preg_replace 的目的是什么?
  • preg_replace 消除 base64 块中常见的空白(换行符)。
  • @Marc,我实际上会在有条件解码后进行健全性检查,与此类似,但我也想进行预测试。至关重要的是,我们不会得到误报。

标签: php regex


【解决方案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)

【讨论】:

  • 是的,就是这样。我不知道\R 会在字符类中崩溃。您知道为什么会这样吗,或者哪些速记在字符类中有效,哪些无效?
  • See here 它说:\R 匹配在 Unicode 规则下可以被视为换行符的任何内容。它不是字符类,因为它可以匹配多字符序列。因此,它不能在括号字符类中使用
猜你喜欢
  • 2018-04-24
  • 2019-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多