我想鏈接content變量內(nèi)的所有標(biāo)記,我可以用foreach實現(xiàn),但是如果一個標(biāo)記是car wash
,另一個是car
,它在link內(nèi)創(chuàng)建鏈接,如何避免呢?
My code:
$tags = Tag::all();
foreach ($tags as $tag) {
if(stripos($content, $tag->name) !== false) {
$content = str_ireplace($tag->name, '<a href="' . route('tag.show', [$tag->id, slug($tag->name)]) . '" target="_blank">' . $tag->name . '</a>', $content);
}
}
其中一個解決方案是按長度對標(biāo)簽進(jìn)行排序,從小到大,但是不,我需要一個更好的解決方案
編輯:將已經(jīng)匹配的標(biāo)記存儲在新數(shù)組中,并在替換前與foreach和strpos檢查它們是否包含子字符串,這將是一個解決方案,但另一個問題,strpost ansstr_replace將匹配部分單詞,例如,如果標(biāo)記是car并且內(nèi)容包含caring,則將存在部分匹配,并且它也將被替換,如何避免部分匹配?
編輯2:謝謝@Kinglish的幫助,最終代碼:
$tags = Tag::orderByRaw('CHAR_LENGTH(name) DESC')->get();
$linkedTags = [];
foreach ($tags as $tag) {
foreach ($linkedTags as $linkedTag) {
if(stripos($linkedTag, $tag->name) !== false) {
continue 2;
}
}
if(stripos($content, $tag->name) !== false) {
$pos = stripos($content, $tag->name);
$disallowedCharacters = [
'-',
'/',
'@',
'\\',
'#',
'*',
'&'
];
if ($pos != 0) {
$charBefore = substr($content, $pos -1, 1);
if (ctype_alpha($charBefore) || ctype_digit($charBefore) || in_array($charBefore, $disallowedCharacters)) {
continue;
}
}
$charAfter = substr($content, $pos + strlen($tag->name), 1);
if (ctype_alpha($charAfter) || ctype_digit($charAfter) || in_array($charAfter, $disallowedCharacters)) {
continue;
}
$linkedTags[] = $tag->name;
$content = str_ireplace($tag->name, '<a href="' . route('tag.show', [$tag->id, slug($tag->name)]) . '" target="_blank">' . $tag->name . '</a>', $content);
}
}
好吧,有個主意也許對你有用。。。
將找到的標(biāo)記存儲在一個數(shù)組中并從內(nèi)容中刪除,這樣它們就不會被提取兩次。然后在最后重新組合內(nèi)容。。。