如何在RE中匹配此特定字符串?

时间:2012-07-27 00:02:56

标签: php regex

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

我正在尝试将[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);

2 个答案:

答案 0 :(得分: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来实现回调内的逻辑。

希望有所帮助。

答案 1 :(得分: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"
  }
}