2016-04-28 11 views
1

Ich arbeite an einem Glossar Auto-Tooltip-Funktion für eine Website. Dies ermöglicht dem Administrator, Glossarbegriffe mit den entsprechenden Definitionen einzugeben, und diese Wörter werden dann an jedem beliebigen Ort, an dem sie am Frontend erscheinen, als ausführbare Tooltip-Trigger verwendet.PHP: Finden Sie Teilstrings, wrap in Tags mit dynamischen Attributen

Hier ist die Methode, die ich bin mit:

Alle Inhalte vor der Ausgabe durch eine Funktion, die für Glossarbegriffe mit einem regulären Ausdruck sucht gefiltert und wickelt sie in Tags mit einer Klasse, die dann nach oben gerichtet durch Javascript, um die Hover-Anzeige des Tooltips zu bearbeiten.

Was ich es tun muss, und nicht herausfinden kann, ist auch die entsprechende Definition als Titelattribut auf der Spannweite enthalten.

Hier ist mein Code so weit:(die ersten Arrays sind nur einige Beispiele, es gibt viele weitere Einträge in jeder)

function glossary_highlight($content) { 
    $glossary = ['Lorem', 'Ipsum']; 
    $definitions = ['Lorem is a type of crocodile', 'Ipsum is a kitchen utensil']; 
    $patterns = []; 
    foreach ($glossary as $term) { 
     $patterns[] = '/\b' . $term . '\b/i'; 
    } 
    $wrapper = '<span class="tooltip" title="XXXX">$0</span>'; 
    $wrapped = preg_replace($patterns, $wrapper, $content); 
    return $wrapped; 
} 

Ich brauche XXXX mit dem entsprechenden Eintrag in der ersetzt werden $ definitionsarray. Ich kann den regulären Ausdruck innerhalb der foreach-Schleife nicht ausführen, da er dann innerhalb der Titel anderer Spanbereiche Spannen hinzufügen kann, wenn eine Definition einen anderen Glossarbegriff usw. enthält.

Der gewünschte Effekt - bei einem $ -Inhalt von "Lorem ipsum dolor sit amet“, sollte die Rückkehr von dieser Funktion sein:

<span class="tooltip" title="Lorem is a type of crocodile">Lorem</span> <span class="tooltip" title="Ipsum is a kitchen utensil">ipsum</span> dolor sit amet 

Meine erste Neigung so etwas wie zu tun war:

$wrapper = '<span class="tooltip" title="' . $definitions[$key] . '">$0</span>'; 

wobei $ Schlüssel zum Index des Glossarbegriff relativ sein würde in Frage, aber ich kann nicht herausfinden, wie man w ork das in die foreach.

Wenn ich nicht alles in PHP herausfinden kann, werde ich einfach die Tooltip-Spanne anwenden und das Definitions-Array an Javascript senden, um das Titelattribut von dort anzuhängen, aber ich würde die grundlegende Aufgabe lieber nicht aufteilen zwei Sprachen ...

Ich bin sicher, dass es hier eine ganz einfache Antwort gibt, aber mein Gehirn wird es nicht sehen! Kann jemand helfen?

EDIT: Dank für seine Hilfe Lampyridae Sie den Code unten funktioniert wie folgt:

function glossary_highlight($content) { 
    $glossary = ['Lorem', 'Ipsum']; 
    $definitions = ['Lorem is a type of crocodile', 'Ipsum is a kitchen utensil']; 
    $patterns = []; 
    foreach ($glossary as $term) { 
     $patterns[] = '/\b' . $term . '\b/i'; 
    } 
    $wrappers = []; 
    foreach ($definitions as $definition) { 
     $wrappers[] = '<span class="tooltip" title="' . $definition . '">$0</span>'; 
    } 
    $wrapped = preg_replace($patterns, $wrappers, $content); 
    return $wrapped; 
} 
+0

zeigen die beispielhaften '$ content' – RomanPerekhrest

+0

Nur ein Heads-up, ich glaube, Ihr Code in etwas albern verhalten könnte Umstände: nämlich Wörter, die Wörter und insbesondere Plural enthalten. Wenn "Pferd" im Glossar steht, wird "Pferde" als " Pferd s" markiert. Wenn "Sequenz" im Glossar steht, wird "conference" als "con sequence" gekennzeichnet. –

+0

Danke, ich habe die Regex aktualisiert, um Wortgrenzen zu verwenden, um dies zu umgehen. – Sark

Antwort

0

Ich sehe zwei Möglichkeiten:

  1. Run preg_replace einmal pro Begriff. Wenn die Texte lang sind, die Begriffe "viele" und "in Echtzeit", kann dies zu einem Leistungsproblem werden.
  2. Stellen Sie eine Reihe von Ersetzungen bereit, genau wie bei Mustern.

Ich denke, Nummer 2 wäre in der Regel schneller und immer noch einfach.Die Idee ist es, Wrapper zu bauen etwa so:

$wrappers = []; 
foreach ($definitions as $definition) { 
    $wrappers[] = '<span class="tooltip" title="' . $definition . '">$0</span>'; 
} 

... dann die Wrapper verwenden:

$wrapped = preg_replace($patterns, $wrappers, $content); 
+1

Ja! Das macht absolut Sinn. Danke x100000 !!!! – Sark

0

Ich würde speichern Sie Ihre Jetons in einem einzigen assoziatives Array. Es ist einfach sauberer und viel einfacher, Übereinstimmungen zu sehen.

$words = [ 
    'lorem' => 'Lorem is a type of crocodile', 
    'ipsum' => 'Ipsum is a kitchen utensil', 
]; 

Dann bauen Sie Muster. Beachten Sie die Verwendung von \ b Wortgrenzenanker hier, so dass wir Lorem aber nicht Splorems zusammenbringen.

$patterns = []; 
foreach (array_keys($words) as $word) { 
    $patterns[] = '/\b' . $word . '\b/i'; 
} 

Dann preg_replace_callback() verwenden einen benutzerdefinierten Ersatz-String on the fly zu generieren:

$newContent = preg_replace_callback($patterns, function ($matches) use ($words) { 
    return 
     '<span class="tooltip" title="' . 
     $words[strtolower($matches[0])] . 
     '">' . $matches[0] . '</span>'; 
}, $content); 
+0

Danke, das ist auch hilfreich. Du hast recht, das assoziative Array ist besser. Danke, dass du mir diese bessere Technik gezeigt hast. – Sark

Verwandte Themen