preg_replace在循环内替换最后一场比赛,而不是每次比赛



对标题感到抱歉,我真的不知道如何正确解释。

我正在制作一个小的shortcode函数,需要用html输出替换shortcode。

preg_match_all找到了我需要的一切,但preg_replace一次又一次地取代了同一场比赛。这是演示https://eval.in/139727

我确信我把前臂的环弄得一团糟,但就是搞不清楚。

$text = 'Some text and some [link link="linkhref1" text="Text1"],[link link="linkhref2" text="Text2"]';

function shortcodes($text) {
    $shortcodes = array(
        'link' => array(
            "check" => "[link",
            "type" => "link",
            "match" => "#[link(.*?)link="(.*?)"(.*?)text="(.*?)"#Ui",
            "replace" => "/[link(.*?)]/s"
        )
    );
    foreach ($shortcodes as $index => $shortcode) {
        if (strpos($text, $shortcode['check']) !== false) {
            $text = shortcode_replace($shortcode, $text);
        }
    }
    return $text;
}

function shortcode_replace($shortcode, $text) {
    $replacement = '';
    preg_match_all($shortcode['match'], $text, $matches);
    switch ($shortcode['type']) {
        case "link":
            foreach ($matches[4] as $index => $match) {
                $link     = $matches[2][$index];
                $linktext = $matches[4][$index];
                $replacement .= '<a href="' . $link . '">' . $linktext . '</a>';
                $text = preg_replace($shortcode['replace'], $replacement, $text);
            }
    }
    return $text;
}

echo shortcodes($text);

感谢您的帮助!

regex中有一个问题,我已经更改了它。此外,您不需要preg_replace。

<?php
$text = 'Some text and some [link link="linkhref1" text="Text1"],[link link="linkhref2" text="Text2"]';

function shortcodes($text) {
    $shortcodes = array(
        'link' => array(
            "check" => "[link",
            "type" => "link",
            "match" => "#[link(s+)link="([^"]+)"(s+)text="([^"]+)"]#Ui",
            "replace" => "/[link(.*?)]/s"
        )
    );
    foreach ($shortcodes as $index => $shortcode) {
        if (strpos($text, $shortcode['check']) !== false) {
            $text = shortcode_replace($shortcode, $text);
        }
    }
    return $text;
}

function shortcode_replace($shortcode, $text) {
    $replace = '';
    preg_match_all($shortcode['match'], $text, $matches);
    switch ($shortcode['type']) {
        case "link":
            var_dump($matches);
            foreach ($matches[4] as $index => $match) {
                $link     = $matches[2][$index];
                $linktext = $matches[4][$index];
                $replace = '<a href="' . $link . '">' . $linktext . '</a>';
                $text = str_replace($matches[0][$index], $replace, $text);
            }
    }
    return $text;
}

echo shortcodes($text);

这里有一个工作版本:

<?php
$text = 'Some text and some [link link="linkhref1" text="Text1"],[link link="linkhref2" text="Text2"]';

function shortcodes($text) {
    $shortcodes = array(
        'link' => array(
            "check" => "[link",
            "type" => "link",
            "match" => "#[link(.*?)link="(.*?)"(.*?)text="(.*?)"#",
            "replace" => "/[link(.*?)]/s"
        )
    );
    foreach ($shortcodes as $index => $shortcode) {
        if (strpos($text, $shortcode['check']) !== false) {
            $text = shortcode_replace($shortcode, $text);
        }
    }
    return $text;
}

function shortcode_replace($shortcode, $text) {
    $replace = '';
    preg_match_all($shortcode['match'], $text, $matches);
    switch ($shortcode['type']) {
        case "link":
            foreach ($matches[4] as $index => $match) {
                $link     = $matches[2][$index];
                $linktext = $matches[4][$index];
                $replace .= '<a href="' . $link . '">' . $linktext . '</a>';
                $whatToReplace = '[link link="'.$link.'" text="'.$linktext.'"]';

                $text = str_replace($whatToReplace, $replace, $text);
            }
    }
    return $text;
}

echo shortcodes($text);

我不太擅长RegExp,我修改了"匹配"来匹配所有链接(与你得到的,它没有)

您需要确定要替换的确切[链接],而不是所有链接。在我看来,这是识别链接的正确方法,您也可以使用strpos()(获取字符串的开始和结束)来识别它,或者查看[链接开始和第一个]在哪里。

一个更好的选择是创建一个具有唯一值的regexp,它可以补偿标记之间的额外空间

希望这对您有帮助

最新更新