【问题标题】:Regex extract variables from [shortcode]正则表达式从 [短代码] 中提取变量
【发布时间】:2013-08-12 20:31:41
【问题描述】:

将一些内容从 WordPress 迁移到 Drupal 后,我需要转换一些短代码:

字符串内容:

不相关的测试... [崇高视频 class="崇高" 海报="http://video.host.com/_previews/600x450/sbx-60025-00-da-ANA.png" src1="http://video.host.com/_video/H.264/LO/sbx-60025-00-da-ANA.m4v" src2="(hd)http://video.host.com/_video/H.264/HI/sbx-60025-00-da-ANA.m4v" 宽度=“560”高度=“315”] ..更多不相关的文字。

我需要在短代码 [sublimevideo ...] 中找到所有变量并将其转换为数组:

Array (
    class => "sublime"
    poster => "http://video.host.com/_previews/600x450/sbx-60025-00-da-FMT.png"
    src1 => "http://video.host.com/_video/H.264/LO/sbx-60025-00-da-FMT.m4v"
    src2 => "(hd)http://video.host.com/_video/H.264/HI/sbx-60025-00-da-FMT.m4v"
    width => "560"
    height => "315"
)

最好处理多个短代码实例。

我想这可以用 preg_match_all() 完成,但我没有运气。

【问题讨论】:

  • 您应该展示您尝试过的内容,我们不是免费的编码服务。这项任务可能会变得相当“困难”,但最好的解决方案之一是使用递归模式来匹配嵌套括号。我的意思是,如果该短代码的内容有 [] 那么下面的正则表达式都会失败。展示你的尝试,我可以帮助你。

标签: php regex drupal shortcode


【解决方案1】:

这会给你你想要的。

$data = 'Irrelevant tekst... [sublimevideo class="sublime" poster="http://video.host.com/_previews/600x450/sbx-60025-00-da-ANA.png" src1="http://video.host.com/_video/H.264/LO/sbx-60025-00-da-ANA.m4v" src2="(hd)http://video.host.com/_video/H.264/HI/sbx-60025-00-da-ANA.m4v" width="560" height="315"] ..more irrelevant text.';

$dat = array();
preg_match("/\[sublimevideo (.+?)\]/", $data, $dat);

$dat = array_pop($dat);
$dat= explode(" ", $dat);
$params = array();
foreach ($dat as $d){
    list($opt, $val) = explode("=", $d);
    $params[$opt] = trim($val, '"');
}

print_r($params);

在处理短代码时您将面临下一个挑战,您可以使用 preg_replace_callback 将短标签数据替换为其生成的标记。

$data = 'Irrelevant tekst... [sublimevideo class="sublime" poster="http://video.host.com/_previews/600x450/sbx-60025-00-da-ANA.png" src1="http://video.host.com/_video/H.264/LO/sbx-60025-00-da-ANA.m4v" src2="(hd)http://video.host.com/_video/H.264/HI/sbx-60025-00-da-ANA.m4v" width="560" height="315"] ..more irrelevant text.';

function processShortCode($matches){
    // parse out the arguments
    $dat= explode(" ", $matches[2]);
    $params = array();
    foreach ($dat as $d){
        list($opt, $val) = explode("=", $d);
        $params[$opt] = trim($val, '"');
    }
    switch($matches[1]){
        case "sublimevideo":
            // here is where you would want to return the resultant markup from the shorttag call.
             return print_r($params, true);        
    }

}
$data = preg_replace_callback("/\[(\w+) (.+?)]/", "processShortCode", $data);
echo $data;

【讨论】:

  • 使用不贪婪的模式 .+? 否则它将匹配到最后一个 ] 括号(在输入中):)
  • @HamZa 你再次巩固了你作为正则表达式之神的地位。 :)
  • Hooo~ 我不是那么好,SO 上有几位伟大的正则表达式大师比我好得多,但我们正在学习! :-)
【解决方案2】:

您可以使用以下 RegEx 来匹配变量:

$regex = '/(\w+)\s*=\s*"(.*?)"/';

我建议首先匹配 sublimevideo 短代码,然后使用以下 RegEx 将其放入字符串中:

$pattern = '/\[sublimevideo(.*?)\]/';

为了获得正确的数组键,我使用了以下代码:

// $string is string content you specified
preg_match_all($regex, $string, $matches);

$sublimevideo = array();
for ($i = 0; $i < count($matches[1]); $i++)
    $sublimevideo[$matches[1][$i]] = $matches[2][$i];

这将返回以下数组:(您请求的那个)

Array
(
    [class] => sublime
    [poster] => http://video.host.com/_previews/600x450/sbx-60025-00-da-ANA.png
    [src1] => http://video.host.com/_video/H.264/LO/sbx-60025-00-da-ANA.m4v
    [src2] => (hd)http://video.host.com/_video/H.264/HI/sbx-60025-00-da-ANA.m4v
    [width] => 560
    [height] => 315
)

【讨论】:

  • 是否可以在 C# 中提供相同的功能?
【解决方案3】:

这是我的解释,我来自 WordPress 背景并尝试为自定义 php 项目重新创建设置。

它将处理诸如 [PHONE] [PHONE abc="123"] 等的事情

它唯一落空的是 WordPress 样式 [这里] 到 [这里]

建立可用简码列表的功能


// Setup the default global variable

function create_shortcode($tag, $function)
{
    global $shortcodes;
    $shortcodes[$tag] = $function;
}

单独定义短代码,例如[IFRAME url="https://www.bbc.co.uk"]:


/**
 * iframe, allows the user to add an iframe to a page with responsive div wrapper
 */
create_shortcode('IFRAME', function($atts) {

    // ... some validation goes here

    // The parameters that can be set in the shortcode
    if (empty($atts['url'])) {
        return false;
    }

    return '
    <div class="embed-responsive embed-responsive-4by3">
      <iframe class="embed-responsive-item" src="' . $atts['url'] . '">
      </iframe>
    </div>';
});

然后,当您想通过短代码处理传递一个 html 块时,请... handle_shortcodes($some_html_with_shortcodes);

function handle_shortcodes($content)
{

    global $shortcodes;

    // Loop through all shortcodes
    foreach($shortcodes as $key => $function){

        $matches = [];

        // Look for shortcodes, returns an array of ALL matches
        preg_match_all("/\[$key([^_^\]].+?)?\]/", $content, $matches, PREG_UNMATCHED_AS_NULL);

        if (!empty($matches))
        {
            $i = 0;
            $full_shortcode = $matches[0];
            $attributes = $matches[1];

            if (!empty($attributes))
            {
                foreach($attributes as $attribute_string) {

                    // Decode the values (e.g. &quot; to ") 
                    $attribute_string = htmlspecialchars_decode($attribute_string);

                    // Find all the query args, looking for `arg="anything"`
                    preg_match_all('/\w+\=\"(.[^"]+)\"/', $attribute_string, $query_args);

                    $params = [];
                    foreach ($query_args[0] as $d) {

                        // Split the
                        list($att, $val) = explode('=', $d, 2);

                        $params[$att] = trim($val, '"');
                    }

                    $content = str_replace($full_shortcode[$i], $function($params), $content);
                    $i++;
                }
            }
        }
    }
    return $content;
}

我从工作代码中提取了这些示例,因此希望它是可读的,并且没有任何我们设置独有的额外功能。

【讨论】:

    【解决方案4】:

    this answer 中所述,我建议让 WordPress 使用 get_shortcode_regex() 函数为您完成工作。

     $pattern = get_shortcode_regex();
     preg_match_all("/$pattern/",$wp_content,$matches);
    

    这将为您提供一个易于使用的数组,并在您的内容中显示各种短代码和附属属性。这不是最明显的数组格式,所以打印出来看看,这样你就知道如何操作你需要的数据了。

    【讨论】:

    • 优秀,记住 OP 想要 Drupal(不是 WordPress)。
    猜你喜欢
    • 1970-01-01
    • 2014-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-05
    • 2014-01-27
    • 1970-01-01
    相关资源
    最近更新 更多