在正则表达式上前瞻

时间:2014-01-06 19:23:28

标签: php regex

我希望在我的代码中完成正常的[img]标记解析之前解析所有附加了链接的bbcode图像,这是因为我的普通[img]标记,如果它们没有链接获取变成了一个灯箱。

    $find = array(
    "/\[url=(.+?)\](?=\[img\](.+?)\[\/img\])\[\/url\]/is"
    );

    $replace = array(
    "<a href=\"$1\" target=\"_blank\"><img src=\"$2\" class=\"bbcodeimage img-polaroid\" alt=\"[img]\" /></a>"
    );

    $body = preg_replace($find, $replace, $body);

完全错误,因为它实际上没有做任何事情,似乎我完全混淆了整个前瞻性的事情来捕获[img]标签之前有[url]并相应地替换。

1 个答案:

答案 0 :(得分:2)

我认为你根本不需要先行。试试这个:

$find = array(
    '~\[url=([^]]+)]\[img]([^[]+)\[/img]\[/url]~i'
);

$replace = array(
    '<a href="$1" target="_blank"><img src="$2" class="bbcodeimage img-polaroid" alt="[img]" /></a>'
);

说明:

首先,我已将模式分隔符更改为~,此更改的目标是避免在模式中转义所有文字/。文字]不需要在字符类之外或在字符类中转义,如果(并且仅当)它是第一个字符。

前瞻在这种情况下没有用,因为前瞻只是一个检查并且什么都不匹配。示例a(?=bc)会找到a后跟bc,但只会匹配a。这就是为什么前瞻和后视也称为“零宽度断言”。

模式细节:

~           # delimiter
\[url=      # literal: [url=
(           # open the first capturing group
    [^]]+   # all characters except ] (one or more times)
)           # close the first capturing group
]           # literal: ]
\[img]      # literal: [img]
(           # open the second capturing group
    [^[]+   # all characters except [ (one or more times)
)           # close the second capturing group
\[/img]     # literal: [/img]
\[/url]     # literal: [/url]
~i          # delimiter and i modifier

请注意,我已选择对替换字符串使用单引号以避免转义字符串的所有双引号(并且因为没有理由使用双引号,没有变量,没有\n或{{ 1}}等。)。