2

我再次陷入正则表达式。没有任何好的材料可以学习更高级的用法。

我正在尝试匹配[image width="740" height="249" parameters=""]51lca7dn56.jpg[/image] $cache->image_tag("$4", $1, $2, "$3").

如果所有[image]参数都在那里,一切都很好,但我需要它匹配,即使缺少某些东西。所以例如[image width="740"]51lca7dn56.jpg[/image]

当前代码是:

$text = preg_replace('#\[image width=\"(.*?)\" height=\"(.*?)\" parameters=\"(.*?)\"\](.*?)\[/image\]#e', '$cache->image_tag("$4", $1, $2, "$3")', $text);

正则表达式是唯一总是让我卡住的东西,所以如果有人也可以参考一些好的资源,这样我就可以自己管理这些类型的问题,我将不胜感激。

我正在尝试做的虚拟版本是这样的:

// match only [image]
$text = preg_replace('#\[image\](.*?)\[/image\]#si', '$cache->image_tag("$1", 0, 0, "")', $text);
// match only width
$text = preg_replace('#\[image width=\"(.*?)\"\](.*?)\[/image\]#si', '$cache->image_tag("$2", $1, 0, "")', $text);
// match only width and height
$text = preg_replace('#\[image width=\"(.*?)\" height=\"(.*?)\"\](.*?)\[/image\]#si', '$cache->image_tag("$3", $1, $2, "")', $text);
// match only all
$text = preg_replace('#\[image width=\"(.*?)\" height=\"(.*?)\" parameters=\"(.*?)\"\](.*?)\[/image\]#si', '$cache->image_tag("$4", $1, $2, $3)', $text);

(这段代码实际上并没有按预期工作,但你会更好地理解我的观点。)我希望基本上把所有这些可怕的混乱都放在一个 RE 调用中。

根据 Ωmega 的回答测试并运行的最终代码:

// Match: [image width="740" height="249" parameters="bw"]51lca7dn56.jpg[/image]
$text = preg_replace('#\[image\b(?=(?:[^\]]*\bwidth="(\d+)"|))(?=(?:[^\]]*\bheight="(\d+)"|))(?=(?:[^\]]*\bparameters="([^"]+)"|))[^\]]*\]([^\[]*)\[\/image\]#si', '$cache->image_tag("$4", $1, $2, "$3")', $text); // the end is #si, so it would be eaiser to debug, in reality its #e

但是,因为如果宽度或高度可能不存在,它将返回空而不是NULL。所以我采用了绘制的想法preg_replace_callback()

$text = preg_replace_callback('#\[image\b(?=(?:[^\]]*\bwidth="(\d+)"|))(?=(?:[^\]]*\bheight="(\d+)"|))(?=(?:[^\]]*\bparameters="([^"]+)"|))[^\]]*\]([^\[]*)\[\/image\]#', create_function(
'$matches',
'global $cache; return $cache->image_tag($matches[4], ($matches[1] ? $matches[1] : 0), ($matches[2] ? $matches[2] : 0), $matches[3]);'), $text);
4

2 回答 2

3

也许尝试像这样的正则表达式来尝试在图像标签中获取额外的参数(如果有的话)。这样,参数可以按任何顺序排列,包含和省略参数的任意组合:

$string = 'this is some code and it has bbcode in it like [image width="740" height="249" parameters=""]51lca7dn56.jpg[/image] for example.';

if (preg_match('/\[image([^\]]*)\](.*?)\[\/image\]/i', $string, $match)) {
    var_dump($match);
}

结果匹配:

array(3) {
  [0]=>
  string(68) "[image width="740" height="249" parameters=""]51lca7dn56.jpg[/image]"
  [1]=>
  string(39) " width="740" height="249" parameters="""
  [2]=>
  string(14) "51lca7dn56.jpg"
}

因此,您可以检查$match[1]并解析出参数。您可能需要使用preg_replace_callback来实现回调内部的逻辑。

希望有帮助。

于 2012-07-27T00:36:46.250 回答
2

我建议你使用正则表达式

\[image\b(?=(?:[^\]]*\bwidth="(\d+)"|))(?=(?:[^\]]*\bheight="(\d+)"|))(?=(?:[^\]]*\bparameters="([^"]+)"|))[^\]]*\]([^\[]*)\[\/image\]

编辑:

$string = 'this is some code and it has bbcode in it like [image width="740" height="249" parameters=""]51lca7dn56.jpg[/image] for example and [image parameters="" height="123" width="456"]12345.jpg[/image].';

if (preg_match_all('/\[image\b(?=(?:[^\]]*\bwidth="(\d+)"|))(?=(?:[^\]]*\bheight="(\d+)"|))(?=(?:[^\]]*\bparameters="([^"]+)"|))[^\]]*\]([^\[]*)\[\/image\]/i', $string, $match) > 0) {
    var_dump($match);
}

输出:

array(5) {
  [0]=>
  array(2) {
    [0]=>
    string(68) "[image width="740" height="249" parameters=""]51lca7dn56.jpg[/image]"
    [1]=>
    string(63) "[image parameters="" height="123" width="456"]12345.jpg[/image]"
  }
  [1]=>
  array(2) {
    [0]=>
    string(3) "740"
    [1]=>
    string(3) "456"
  }
  [2]=>
  array(2) {
    [0]=>
    string(3) "249"
    [1]=>
    string(3) "123"
  }
  [3]=>
  array(2) {
    [0]=>
    string(0) ""
    [1]=>
    string(0) ""
  }
  [4]=>
  array(2) {
    [0]=>
    string(14) "51lca7dn56.jpg"
    [1]=>
    string(9) "12345.jpg"
  }
}
于 2012-07-27T00:40:54.767 回答