Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Έχω βρει/ συνθέσει από το διαδίκτυο την ακόλουθη PHP function για μια ajax μηχανή αναζήτησης σε PHP, η οποία δέχεται το $text (για κάθε result/row) και το $words (query αναζήτησης) και αλλάζει το χρώμα του κειμένου που γίνεται η αναζήτηση, το κάνει highlighted δλδ.

	function highlighter_text($text, $words)
	{
		$split_words = explode( " " , $words );
		foreach($split_words as $word)
		{
			$text = preg_replace("|($word)|Ui" ,
				"<span class=\"sc_search_highlighted\"><b>$1</b></span>" , $text);
		}
		return $text;
	}	

Οπότε μέσα σε μια loop για κάθε αποτέλεσμα που βρέθηκε (προφανώς στο "περίπου" και όχι ακριβής φράση), κάνω το εξής:

$row['text'] = highlighter_text($row['text_initial'], $query);

Το πρόβλημα: σε κάποια αποτελέσματα επιστρέφεται εσφαλμένη σύνταξη HTML.

Παράδειγμα, αν υπάρχει στα αποτελέσματα η φράση "Dota 2 test", με το που θα γράψεις και το τελευταίο γράμμα της μερικής φράσης "Dota 2 t" (μιλάμε για onkeyup ajax επιστροφή αποτελεσμάτων), επιστρέφεται το εξής σύμφωνα με την κονσόλα:

<span class="sc_search_highligh<span class=" sc_search_highlighted"=""><b>t</b></span>ed"><b>Do<span class="sc_search_highlighted"><b>t</b></span>a</b> <span class="sc_search_highligh<span class=" sc_search_highlighted"=""><b>t</b></span>ed"><b>2</b> <span class="sc_search_highlighted"><b>t</b></span>es<span class="sc_search_highlighted"><b>t</b></span>

... ενώ αν ολοκληρώσεις όλη τη φράση, το αποτέλεσμα είναι σωστό:

<span class="sc_search_highlighted"><b>Dota</b></span> <span class="sc_search_highlighted"><b>2</b></span> <span class="sc_search_highlighted"><b>test</b></span>

Αντιλαμβάνομαι ότι το θέμα είναι μάλλον ότι όταν έχει πατηθεί μόνο το πρώτο γράμμα μιας λέξης στο πεδίο αναζήτησης, αυτό γίνεται αντιληπτό ως "word" και εφαρμόζει το <span> πολλαπλές φορές ακόμα και στις words που έχουν ήδη προσεσσαριστεί και πχ στην προκειμένη το γράμμα "t" γίνεται replace ακόμα και στο "sc_search_highligh<span class=" sc_search_highlighted"=""><b>t</b></span>".

 

Δε θέλω να κάνω if (strlen($word) == 1) continue; γιατί θέλω να γίνεται highlight ακόμα και το ένα γράμμα, χωρίς να χαλάει η δομή της html.

 

Καμία πρόταση για λύση; :-)

Δημοσ.

Τροφη για σκέψει...

Κάνε explode στις λέξεις της βάσεις και αποθηκευσε ολλες τις πιθανες λέξεις. Ετσι θα ψαχνεις στις λεξεις και μονο αν τη βρει να κάνει highlight.

Δημοσ.

Κάτι πιο απλό δεν παίζει; :-D

Απλά θέλω ταίριασμα με highlight μεταξύ του $row['text_initial'] και του $query και παράλληλα τα πεζά/ κεφαλαία να αντιστοιχίζονται στο αποτέλεσμα και όχι στο $query.

 

Πχ αν υπάρχει η φράση This is a test και ο χρήστης πληκτρολογήσει A TEST, θα πρέπει το αποτέλεσμα να γίνει:

This is a test

Δημοσ.

Προφανώς το πρόβλημά σου είναι ότι τα μετέπειτα replace μετά το πρώτο κάνουν match τα highlight από τα προηγούμενα σα να ήταν τμήμα του αρχικού κειμένου.

 

Επομένως η λύση είναι είτε να τα κάνεις "όλα μαζί" είτε με κάποιο τρόπο να αποφύγεις την εισαγωγή highlights στο string μέχρι να τελειώσουν όλα τα matches (δε λέω replace γιατί τότε προφανώς δεν αποφεύγεις τίποτα).

 

Επίσης πρέπει να κάνεις κατάλληλα preg_quote τα words γιατί αλλιώς αν περιέχουν regex syntax επίτηδες ή κατα λάθος θα έχεις θέματα.

 

Π.χ.

$words = array_map('preg_quote', $words);
$wordsRegex = '(' . implode('|', $words) . ')';
$text = preg_replace("/$wordsRegex/Ui" , ....); // μόνο μία φορά
  • Like 1
  • 2 μήνες μετά...
Δημοσ.

Καλησπέρα και πάλι!

Χρησιμοποιώ για άλλη μια φορά την ακόλουθη function, σε άλλη εφαρμογή και με ελληνικά, βάσει της πρότασης του defacer για να κάνω το highlight:

function highlight_keyword($text, $words)
{
        $color = 'red';
        $words = explode( " " , $words );
        $words = array_map('preg_quote', $words);
        $wordsRegex = '(' . implode('|', $words) . ')';
        $text = preg_replace("/$wordsRegex/Ui" , "<span style=\"color: $color !important; padding-left:0px !important; text-transform:none !important;\"><b>$1</b></span>", $text);    
        return $text;
}

 

Με αγγλικά λειτουργεί όπως πρέπει.

Ωστόσο υπάρχει το εξής θέμα με τα ελληνικά. Αν βάλω $words:

Αναφορά σε κείμενο

ηλικία

Κάνει σωστό highlight στο $text:

Αναφορά σε κείμενο

ηλικία

 

Αν γράψω όμως στην αναζήτηση:

Αναφορά σε κείμενο

Ηλικία

δεν γίνεται highlight η λέξη:

Αναφορά σε κείμενο

ηλικία

... μέσα στο αποτέλεσμα / $text.

Καμία ιδέα; Στα αγγλικά, ανεξαρτήτως πεζών ή κεφαλαίων, δεν υπάρχει κανένα πρόβλημα.

Απλά θέλω και στα ελληνικά να γίνεται το highlight, ανεξαρτήτως κεφαλαίων ή πεζών. ;)

Δημοσ.

Πάρε τη μεταβλητή που περιέχει αυτό που έγραψες στην αναζήτηση και κάντην bin2hex(). Κάνε το ίδιο με το text που δεν γίνεται highlighted (αν μπορείς να κόψεις λίγο το text για να μικρύνει σε έκταση αφαιρώντας άσχετα τμήματά του, ακόμα καλύτερα).

Μην το κάνεις γράφοντας μόνος σου σε άσχετο σημείο. Πρέπει να είναι ακριβώς τα ίδια δεδομένα που έχεις και στο πρόγραμμα. Ούτε copy paste ούτε τίποτα.

Πόσταρε εδώ το αποτέλεσμα.

Δημοσ.

Πειράζει που δεν κατάλαβα; -_-:P

Στην function highlight_keyword, δοκίμασα να τρέξω και στο $words (query αναζήτησης) και στο $text (αποτέλεσμα), την bin2hex, αλλά χωρίς αποτέλεσμα.

Και βασικά δεν έχω καταλάβει ποιο το point του να μετατραπεί το κείμενο σε hex.

Δημοσ. (επεξεργασμένο)
1 hour ago, philos said:

Και βασικά δεν έχω καταλάβει ποιο το point του να μετατραπεί το κείμενο σε hex.

Το point είναι να κάνουμε debugging στο γιατί δε σου δουλεύει σε πρώτη φάση με τη μέθοδο του αποκλεισμού. Συγκεκριμένα σκέφτομαι ότι μπορεί για να δουλέψει η regex να πρέπει και το text και το pattern να πρέπει να βρίσκονται στο ίδιο normalization form. Δε δίνω μεγάλες πιθανότητες να ισχύει αυτό και να μην είναι στο ίδιο form στην περίπτωσή σου, αλλά πριν αρχίσουμε να κυνηγάμε βρούβες ας αποκλείσουμε τα ενδεχόμενα που είναι εύκολο να εξεταστούν και να διορθωθούν.

Βρούβες = διάβασμα source κώδικα PHP και PCRE και ICU. Σίγουρη μέθοδος για να βρεθεί η λύση αν έχεις πολλές γνώσεις, είσαι γκουρού στη C, και σου περισσεύει ένα ολόκληρο απόγευμα.

Επεξ/σία από defacer

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...