preg_replace verschluckt Leerzeichen, oder doch nicht?
snoot
- php
Hio,
sorry wegen dem verwirrenden Titel, aber genau so merkwürdig ist mein Problem.
Ich verarbeite Benutzereingaben mittels Ajax und liefere passende Wortvorschläge als Liste dafür zurück (Ajax Suggest).
Gibt der Besucher "Unter" ein, erhält er z.B. "Unterdruck", "Unterlage" und "Unterschied" zurück. Gleichzeitig wird der übereinstimmende String ("Unter") in den Vorschlägen mittels preg_replace fett formatiert:
$anzeige_fett = preg_replace("/($eingabe)/i", "<strong>$1</strong>", $anzeige, 1);
Das klappt soweit auch, allerdings tritt bei zwei Wörtern (durch Leerzeichen getrennt) folgendes Problem auf: ist das erste Wort vollständig eingegeben, wird das Leerzeichen zwischen den beiden Wörtern ausgeblendet.
Beispiel:
Eingabe: Anzeige der Vorschläge:
Amorphe Amorphes Silicium
Amorphes AmorphesSilicium // das Leerzeichen verschwindet
Amorphes_ Amorphes Silicium // _ soll ein Leerzeichen sein
Amorphes S Amorphes Silicium
Hat jemand eine Idee, was mit dem Leerzeichen passiert?
Die ganze DB-Abfrage:
$suggest = sprintf("SELECT ausgabe, anzeige FROM suggest WHERE anzeige LIKE '%s%%' ORDER BY anzeige LIMIT $limit;", mysql_real_escape_string($eingabe));
$suggest = mysql_query($suggest);
while ($antwort=mysql_fetch_array($suggest))
{
$anzeige = $antwort["anzeige"];
$ausgabe = $antwort["ausgabe"];
if(strcasecmp($eingabe, $anzeige) != 0)
{
$anzeige_fett = preg_replace("/($eingabe)/i", "<strong>$1</strong>", $anzeige, 1);
$liste .= ' <li><a id="'.htmlspecialchars($ausgabe).'" onclick="insert_eingabe(id, \''.$txt_id.'\', \''.$div_id.'\')" href="#"> '.$anzeige_fett.'</a></li>';
$count++;
}
}
Wenn ich mir die Ausgabe in Firebug anschaue, dann ist das Leerzeichen aber immer vorhanden, nur in der Vorschlagsliste sieht man es nicht mehr.
Firebugausgabe:
<li><a id=""Amorphes Silicium"" onclick="insert_eingabe(id, 'eingabe', 'suggests')" href
="#"> <strong>Amorphes</strong> Silicium</a></li>
Moin!
$anzeige_fett = preg_replace("/($eingabe)/i", "<strong>$1</strong>", $anzeige, 1);
Für das, was du da willst, sind reguläre Ausdrücke eindeutig überzogen. Ein schlichtes str_replace() bzw. str_ireplace() würde vollkommen ausreichen.
Denn was dir eindeutig fehlt, ist ein Escaping der Variablen $eingabe im Hinblick auf Sonderzeichen, die ein regulärer Ausdruck kennen kann. Wenn man das Falsche sucht (beispielsweise etwas mit schließender runder Klammer), dann zerhaut es dir den Regex.
Nicht auszuschließen, dass dir so ein Seiteneffekt schon jetzt die Show kaputt macht.
Wenn ich mir die Ausgabe in Firebug anschaue, dann ist das Leerzeichen aber immer vorhanden, nur in der Vorschlagsliste sieht man es nicht mehr.
Firebugausgabe:
<li><a id=""Amorphes Silicium"" onclick="insert_eingabe(id, 'eingabe', 'suggests')" href
="#"> <strong>Amorphes</strong> Silicium</a></li>
So sieht man hier, was du eingegeben hast?
- Sven Rautenberg
Für das, was du da willst, sind reguläre Ausdrücke eindeutig überzogen. Ein schlichtes str_replace() bzw. str_ireplace() würde vollkommen ausreichen.
Da kann ich aber nicht vorgeben, dass der String nur einmal ersetzt werden soll!?
Denn was dir eindeutig fehlt, ist ein Escaping der Variablen $eingabe im Hinblick auf Sonderzeichen, die ein regulärer Ausdruck kennen kann.
Sorry, davor steht noch ein $eingabe = preg_quote($eingabe);
So sieht man hier, was du eingegeben hast?
Egal was ich hier eingegeben habe ("Amorph", "Amorphes", "Amorphes ", "Amorphes S"), die Ausgabe in Firebug ist immer korrekt, mit Leerzeichen, aber in der ausgegebenen Liste auf der Seite ist das Leerzeichen weg.
Hi,
Hat jemand eine Idee, was mit dem Leerzeichen passiert?
PHP-seitig wohl erst mal gar nichts, schliesslich schreibst du:
Wenn ich mir die Ausgabe in Firebug anschaue, dann ist das Leerzeichen aber immer vorhanden, nur in der Vorschlagsliste sieht man es nicht mehr.
Dann wird es wohl ein clientseitiges Problem sein.
Irgendeine Formatierung oder sonstwas, was da noch greift und die Darstellung entsprechend beeinflussen könnte?
Gibt's das online zu sehen? Gerne auch ein reduziertes Testbeispiel, von mir aus sogar statisch (ohne AJAX), wenn es sich damit auch nachstellen lässt.
MfG ChrisB
Irgendeine Formatierung oder sonstwas, was da noch greift und die Darstellung entsprechend beeinflussen könnte?
Ja, jetzt wo du es sagst - und wo ich noch mal hingeschaut habe.
Das Leerzeichen verschwindet auch, wenn man das erste Wort + Leerzeichen eingegeben hat. Also erst mit dem ersten Buchstaben des nächsten Wortes ist es wieder da.
Grund ist diese Funktion um unnötige Whitespaces zu entfernen:
function clearSpaces (strOut)
{
strOut = strOut.replace(/>\s+/gm,'>');
strOut = strOut.replace(/\s+</gm,'<');
strOut = strOut.replace(/>\s+</gm,'><');
return strOut;
};
Aber bei den strong-Tags taucht ja unmittelbar davor/danach ein Leerzeichen auf, welches hier entfernt wird: "<strong>Amorphes</strong> Silicium".
Daran habe ich ja gar nicht mehr gedacht. Danke für den Denkanstoß :)