【问题标题】:Multiple items and preg_replace_callback多个项目和 preg_replace_callback
【发布时间】:2012-12-12 13:20:04
【问题描述】:

我编写了这个脚本,以便能够在我的代码中使用类似 bb-code 的标签。在花了很多时间决定最佳方法并在How to dynamically replace bb tags? 询问之后,我决定使用 preg_replace_callback。

但是在同一行有多个项目存在问题

Man [forvo=man,nl]
Mannen [forvo=mannen,nl]

上面的部分有效,但下面的部分无效。

Kip [forvo=kip,nl] - Kippen [forvo=kippen,nl]
Bal [forvo=bal,nl] - Ballen [forvo=ballen,nl]
Vrouw [forvo=vrouw,nl] - Vrouwen [forvo=vrouwen,nl]

我知道使用 file_get_contents() 不是推荐选项,但如果我想每行使用多个 Forvo-tags,我是否还应该找到其他解决方案而不是 preg_replace_callback?

<?php
// Replace forvos in the lesson
$lesson_body = $lesson['Lesson']['body'];

function forvize($match) {
    $word = $match[1];
    $language = $match[2];
    $link = "http://apifree.forvo.com/action/word-pronunciations/format/js-tag/word/".$word."/language/".$language."/order/rate-desc/limit/1/key/API_KEY/";
    $link = file_get_contents($link);
    return $link;
}

//URL's
$lesson_body = preg_replace_callback("/\[forvo\=(.*),(.*)\]/", 'forvize', $lesson_body);

?>

【问题讨论】:

    标签: php preg-replace preg-replace-callback


    【解决方案1】:

    你犯的错误很常见。默认情况下,句号(.,也称为 dot)匹配除换行符以外的任何字符。因此,如果您在一行上只有一个 bbcode,这没问题:

    /\[forvo\=(.*),(.*)\]/
    

    但如果一行中的 bbcode 不止一个,点将尽可能多地匹配模式:

    [forvo=aaaa,bbbbb] ... [forvo=cccc,dddd]
           (.*                       ),(.*)
    

    您可以改为将第一个参数限制为除逗号 (,) 之外的所有字符,将第二个参数限制为除右方括号 (]) 之外的所有字符。

    例子:

    /\[forvo\=([^,]*),([^\]]*)\]/
    

    【讨论】:

      【解决方案2】:

      捕获这些的一种方法是使用不贪婪的量词(又名问号)来使其捕获所有内容,直到模式中第一次出现以下字符。

      ~\[forvo=(.*?),(.*?)\]~

      • 第一个带括号的组匹配从等号到第一个逗号的所有内容
      • 第二个匹配逗号后的所有内容,直到右方括号

      另一个选项是让它捕获除特定字符之外的任何内容(在这种情况下分别为逗号和右括号)。检查@hakre 的答案,看看它是如何完成的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-07
        • 2012-12-19
        • 1970-01-01
        • 1970-01-01
        • 2016-06-22
        • 2015-03-03
        相关资源
        最近更新 更多