Лучшим примером может быть следующее:
$string = "That is a very nice ford mustang, if only every other ford was quite as nice as this honda";
Я хочу заменить названия автомобилей ссылкой для производителя и модели, если они совпадают, или просто производитель, но если есть марка и модель, она помещает ссылки в ссылки, если вы используете, например, замену str …
$remove = array("ford mustang","ford","honda"); $replaceWith = array("<a href='fordID'>ford</a>","<a href='fordmustangID'>ford mustang</a>","<a href='hondaID'>honda</a>");
Это дает результат:
"That is a very nice <a href='<a href='fordmustangID'>ford mustang</a>ID'><a href='fordmustangID'>ford mustang</a></a>, if only every other <a href='fordmustangID'>ford mustang</a> was quite as nice as this <a href='hondaID'>honda</a>"
Я только хочу, чтобы он создал гиперссылку, если ее уже нет:
"That is a very nice <a href='fordmustangID'>ford mustang</a>, if only every other <a href='fordID'>ford</a> was quite as nice as this <a href='hondaID'>honda</a>"
Принял меня хорошо, но вот что я придумал:
function replaceLinks($replacements, $string){ foreach($replacements as $key=>$val){ $key=strtolower((string)$key); $newReplacements[$key]=array(); $newReplacements[$key]['id']=$val; //strings to make sure the search isn't in front of $newReplacements[$key]['behinds']=array(); //strings to make sure the search isn't behind $newReplacements[$key]['aheads']=array(); //check for other searches this is a substring of foreach($replacements as $key2=>$val2){ $key2=(string)$key2; /* //debugging $b = ($key=='11 22'&&$key2=='11 22 33'); if($b){ l('strlen $key2: '.strlen($key2)); l('strlen $key: '.strlen($key)); l('strpos: '.(strpos($key2,$key))); } */ //the second search is longer and the first is a substring of it if(strlen($key2)>strlen($key) && ($pos=strpos($key2,$key))!==false){ //the first search isn't at the start of the second search ('the ford' and 'ford') if($pos!=0){ $newReplacements[$key]['behinds'][]=substr($key2,0,$pos); } //it's not at the end ('ford' and 'fords') if(($end=$pos+strlen($key))!=strlen($key2)){ $newReplacements[$key]['aheads'][]=substr($key2,$end); } } } } foreach($newReplacements as $key=>$item){ //negative lookbehind for words or > $tmp="/(?<![\w>=])"; //negative lookbehinds for the beginnings of other searches that this search is a subtring of foreach($item['behinds'] as $b){ $tmp.="(?<!$b)"; } //the actual search $tmp.="($key)"; //negative lookaheads for ends of other searches that this is a substring of. foreach($item['aheads'] as $a){ $tmp.="(?!$a)"; } //case insensitive $tmp.='/ie'; $replacementMatches[]=$tmp; } return preg_replace($replacementMatches,'"<a href=\"".$newReplacements[strtolower("$1")]["id"]."\">$1</a>"' ,$string); }
Передайте ему массив, такой как тот, о котором вы говорили:
$replaceWith = array('ford mustang'=>123,'ford'=>42,'honda'=>324);
и строка:
$string = "That is a very nice ford mustang, if only every other ford was quite as nice as this honda"; echo replaceLinks($replaceWith,$string);
Он дает преимущество перед большими строковыми клавишами, поэтому, если у вас есть ford
и ford mustang
, он заменит ford mustang
ссылкой.
Не очень практично, но может работать.
$string = "That is a very nice ford mustang, if only every other ford was quite as nice as this honda"; $remove = array("/(?<![\w>])ford mustang(?![\w<])/",'/(?<![>\w])ford(?! mustang)(?![<\w])/',"/(?<![>\w])honda(?![<\w])/"); $replaceWith = array("<a href='fordmustangID'>ford mustang</a>","<a href='fordID'>ford</a>","<a href='hondaID'>honda</a>"); echo preg_replace($remove, $replaceWith,$string);
Я использовал регулярные выражения с отрицательными lookaheads и lookbehinds, чтобы убедиться, что часть строки, которую мы заменяем, не является частью буквенно-цифровой последовательности (например, 12ford23
или позволяет) или касаться начального или конечного тега элемента.