![](/img/trans.png)
[英]RegEx for PHP preg_replace swapping matches and matching multiple instances
[英]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.