【问题标题】:preg_match(): Compilation failed: missing terminating ] for character class with escaped \ [duplicate]preg_match(): 编译失败: 缺少字符类的终止符 \ [重复]
【发布时间】:2017-05-25 11:27:26
【问题描述】:

我正在尝试在 JSON 字符串上运行正则表达式以验证数据是否符合预期,然后再继续执行我的脚本。

下面是运行正则表达式的 JSON 示例:

[{"id":"01001001","b":"1","c":"1","v":"1","t":"Some \"Text\""},{"id":"01001002","b":"1","c":"1","v":"2","t":"More Text"},{"id":"01001003","b":"1","c":"1","v":"3","t":"And Even More"}]

我已经在phpliveregex.com 测试了以下正则表达式:

\[(\{"id":"[0-9]{8}","b":"[0-9]{1,2}","c":"[0-9]{1,2}","v":"[0-9]{1,3}","t":"[^"\\]*(?:\\.[^"\\]*)*"\})(,\{"id":"[0-9]{8}","b":"[0-9]{1,2}","c":"[0-9]{1,2}","v":"[0-9]{1,3}","t":"[^"\\]*(?:\\.[^"\\]*)*"\})*\]

这是我在 PHP 中的组合方式:

$sv = '01001001';
$ev = '01001003';
$url = 'http://api.amasterdesigns.com/?sv='.$sv.'&ev='.$ev;
$JSON = file_get_contents($url);
//return JSON only if properly formatted
if(preg_match('/\[(\{"id":"[0-9]{8}","b":"[0-9]{1,2}","c":"[0-9]{1,2}","v":"[0-9]{1,3}","t":"[^"\\]*(?:\\.[^"\\]*)*"\})(,\{"id":"[0-9]{8}","b":"[0-9]{1,2}","c":"[0-9]{1,2}","v":"[0-9]{1,3}","t":"[^"\\]*(?:\\.[^"\\]*)*"\})*\]/',$JSON)){
    return json_decode($JSON);
} else {
    return;
}

我收到的问题是当我运行此页面时收到此错误

警告:preg_match():编译失败:缺少终止] for 偏移量 202 处的字符类 path_to_file/my-file.php 第 1422 行

第 1422 行是上述代码 sn-p 的第 6 行。我相信这是在我的正则表达式末尾附近指向[^"\\],但我确实在转义\ 之后有一个终止]

您可以使用PHP sandbox查看错误

【问题讨论】:

  • 您为什么尝试使用正则表达式解析 JSON 而不是使用 json_decode()
  • 我想确保数据在解码之前符合我的预期。
  • 解码JSON然后验证内容会容易得多。
  • 更具体地说,我在 WordPress 插件中使用此代码,并希望在公共端输出错误之前添加另一层验证,以防检索 JSON 的 API 出现错误响应.
  • 解析JSON,检查json_last_error,然后遍历解析的对象/数组来验证数据比把它全部塞进一个正则表达式要容易得多。

标签: php json regex compiler-warnings


【解决方案1】:

这部分:

[^"\\]

需要:

[^"\\\\]

您需要再次将反斜杠加倍,因为它们在字符串和正则表达式语法中都充当转义符。当\\ 被发送到preg_match 时,它会变成\,这是对] 的转义,而不是将反斜杠视为字符集中的字符之一。

【讨论】:

  • 谢谢。将此修复应用于每个 \\
【解决方案2】:

v 的第一次检查缺少一个开口[

"v":"0-9]{1,3}"  // should be:
"v":"[0-9]{1,3}"

【讨论】:

  • 我很抱歉在我的问题中复制/粘贴和格式化我的代码时出错。这个开头[ 已经到位。请参阅编辑。
  • 这里没有必须。单独的右括号并不意味着正则表达式中的特殊字符。
  • @revo 否,但如果您尝试匹配 0-9 范围内的 1-3 个字符,PECL 将需要一个在那里您想要的工作。否则,它将查找文字字符串“0-9”,后跟 1-3 个“]”字符。
  • PECLPCRE?
  • @revo 把我的首字母缩写词弄混了。你是对的,我的意思是PCRE。对不起!
【解决方案3】:

添加到@Barmar 的答案,或将您的正则表达式包装成nowdoc 格式:

$re = <<< 'RE'
/\[(\{"id":"[0-9]{8}","b":"[0-9]{1,2}","c":"[0-9]{1,2}","v":"[0-9]{1,3}","t":"[^"\\]*(?:\\.[^"\\]*)*"\})(,\{"id":"[0-9]{8}","b":"[0-9]{1,2}","c":"[0-9]{1,2}","v":"[0-9]{1,3}","t":"[^"\\]*(?:\\.[^"\\]*)*"\})*\]/
RE;

if (preg_match($re, $JSON)) {
    print_r(json_decode($JSON));
}

【讨论】:

    猜你喜欢
    • 2011-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-16
    • 1970-01-01
    • 2018-11-15
    • 2014-11-30
    • 1970-01-01
    相关资源
    最近更新 更多