【问题标题】:Correcting an illegal PCRE regex in PHP更正 PHP 中的非法 PCRE 正则表达式
【发布时间】:2013-05-25 20:32:18
【问题描述】:

5 月 26 日更新

我已经修复了之前包含在这个问题中的正则表达式的行为,但是正如其他人所提到的,我的语法仍然不正确。显然它编译的事实是由于 PHP 的 preg_* 系列函数忽略了我的错误。

我绝对是 PCRE 新手,所以我试图了解存在哪些错误,以便我可以着手修复它们。我也愿意对设计/方法进行批评,正如其他人所提到的,我还将构建与 JSON 和 YAML 的兼容性,但我想继续完成这个自制的解析器,因为我有了它工作,我只需要处理表达式语法(我认为)。

这是从整页代码中提取的所有preg_match_all 引用和一个preg_replace 引用:

// matches the outside container of objects {: and :}
$regex = preg_match_all('/\s\{:([^\}]+):\}/i', $this->html, $HTMLObjects);

// double checks that the object container is removed
$markup = preg_replace('/[\{:]([^\}]+):\}/i', '$1', $markup);

// matches all dynamic attributes (those containing bracketed data)
$dynamicRegEx = preg_match_all('/[\n]+([a-z0-9_\-\s]+)\[([^\]]+)\]/', $markup, $dynamicMatches);

// matches all static attributes (simple colon-separated attributes)
$staticRegEx = preg_match_all('/([^:]+):([^\n]+)/', $staticMarkup, $staticMatches);

如果您想在上下文中查看 preg_match_allpreg_replace 引用,以便您也可以评论/批评,您可以通过以下链接查看包含的源文件。

注意:查看页面的源代码可以使所有内容更具可读性 http://mdl.fm/codeshare.php?htmlobject

就像我说的,我让它按现状运行,我只是要求对我的 PCRE 语法进行监督,以免它不合法。但是,如果您在结构/设计或其他方面有 cmets,我愿意接受所有建议。

【问题讨论】:

    标签: php regex preg-match preg-match-all pcre


    【解决方案1】:

    (重写以反映新问题)

    第一个正则表达式是正确的,但您不需要在字符类中转义}。另外,我通常包含两个大括号以避免匹配嵌套对象(您的正则表达式将匹配字符串"{:foo {:bar:} baz:}" 中的{:foo {:bar:}),我的只会匹配{:bar:}/i 模式修饰符没有用,因为您的正则表达式中没有大小写文本。

    // matches the outside container of objects {: and :}
    $regex = preg_match_all('/\s\{:([^{}]+):\}/', $this->html, $HTMLObjects);
    

    在您的第二个正则表达式中,开头有一个不正确的字符类需要删除。否则,它是一样的。

    // double checks that the object container is removed
    $markup = preg_replace('/\{:([^{}]+):\}/', '$1', $markup);
    

    您的第三个正则表达式看起来不错;不过,还有另一个无用的字符类。同样,我在否定字符类中包含了两个括号。我不知道你为什么让它区分大小写 - 这里不应该有一个 /i 修饰符吗?

    // matches all dynamic attributes (those containing bracketed data)
    $dynamicRegEx = preg_match_all('/\n+([a-z0-9_\-\s]+)\[([^\[\]]+)\]/i', $markup, $dynamicMatches);
    

    最后一个正则表达式是可以的,但它总是从字符串的第一个字符到第一个冒号(然后到该行的其余部分)匹配。我想我会在第一个否定字符类中添加一个换行符,以确保不会发生这种情况:

    // matches all static attributes (simple colon-separated attributes)
    $staticRegEx = preg_match_all('/([^\n:]+):([^\n]+)/', $staticMarkup, $staticMatches);
    

    【讨论】:

    • 它不在字符类中,它们是捕获组之前的文字括号,除非您引用其他内容。所以没有让我发布转义斜线,但你是在谈论第一个正则表达式吗?
    • @danL:是的,这是关于第一个正则表达式。你是什​​么意思,所以不允许你发布反斜杠?当然可以。
    • 在阅读了您的建议后,我已经使用我现在使用的正则表达式更新了我的问题。如果它们仍然是非法的,你能告诉我吗?谢谢。
    猜你喜欢
    • 2014-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多