簡體   English   中英

PHP:正則表達式匹配和替換多個匹配項的多個實例被復制

[英]PHP: Regex matching and replacing multiple instances of multiple matches being duplicated

我正在為游戲社區/數據庫編寫一個簡碼系統,用戶可以在其中添加((Magical Sword))類的內容到他們的內容中,它會被解析為一個很好的鏈接,指向帶有內聯縮略圖的相關項目.

這是我目前使用的代碼:

function inlineItems($text) {
    $re = "/\(\(([^)]+)\)\)/m";
    preg_match_all($re, $text, $matches, PREG_SET_ORDER, 0);
    foreach($matches as $match) {
        $slug = makeSlug($match[1]);
        $item = getItem($slug);
        if($item) {
            $text = preg_replace($match[0], '<a class="text-item" data-tooltip="tooltip-item-' . $item->slug . '" href="/items/' . $item->slug .'"><img src="/images/items/' . $item->slug .'.png">' . $item->name .'</a>', $text);
        }
    }
    $text = str_replace("((", "", $text);
    $text = str_replace("))", "", $text);
    return $text;
}

示例 output,如果用戶輸入((Crystal Sword))將是:

<a class="text-item" data-tooltip="tooltip-item-crystal-sword" href="/items/crystal-sword"><img src="/images/items/crystal-sword.png">Crystal Sword</a>

到目前為止一切順利,一切都很好。

但是,當特定匹配項在一個文本字符串中重復多次時會出現問題。

如果用戶輸入如下內容: A ((Crystal Sword)) is essential for farming, get a ((Crystal Sword)) as soon as you can. ((Crystal Sword)) is the best! A ((Crystal Sword)) is essential for farming, get a ((Crystal Sword)) as soon as you can. ((Crystal Sword)) is the best! 然后替換多次匹配項目名稱,並以這樣的混亂結束:

<a class="text-item" data-tooltip="tooltip-item-crystal-sword" href="/items/crystal-sword"><img src="/images/items/crystal-sword.png"></a><a class="text-item" data-tooltip="tooltip-item-crystal-sword" href="/items/crystal-sword"><img src="/images/items/crystal-sword.png"></a><a class="text-item" data-tooltip="tooltip-item-crystal-sword" href="/items/crystal-sword"><img src="/images/items/crystal-sword.png">Crystal Sword</a>

如何防止它像這樣重疊匹配?

你的代碼很亂。 您不需要所有這些替換,一個就足夠了。 遵循 KISS 原則:

<?php

function inlineItems($text) {

    $re = "/\(\((.+?)\)\)/m";

    return preg_replace_callback($re, function($matches){

        $item = getItem( makeSlug($matches[1]) );

        return "<a class='text-item' data-tooltip='tooltip-item-{$item->slug}' href='/items/{$item->slug}'>
            <img src='images/items/{$item->slug}.png'>
            {$item->name}
        </a>";

    }, $text);

}


print inlineItems('A ((Crystal Sword)) is essential for farming, get a ((Crystal Sword)) as soon as you can. ((Crystal Sword)) is the best!');

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM