2010-07-20 10 views
17

Sto provando a scrivere una "casella di ricerca dei suggerimenti" e non riesco a trovare una soluzione che permetta di evidenziare una sottostringa con javascript mantenendo la custodia originale.Javascript: evidenzia la sottostringa mantenendo il caso originale ma cercando in modalità maiuscole/minuscole

Per esempio se la ricerca di "ca" che cerco lato server in una modalità insensibile caso e ho i seguenti risultati:

Calculator

calendario

ESCAPE

lo farei piace vedere la stringa di ricerca in tutte le parole precedenti, quindi il risultato dovrebbe essere:

Ca lculator

ca lendar

ES CA PE

ho provato con il seguente codice:

reg = new RegExp(querystr, 'gi'); 
final_str = 'foo ' + result.replace(reg, '<b>'+querystr+'</b>'); 
$('#'+id).html(final_str); 

Ma ovviamente in questo modo ho sciolto il caso originale!

C'è un modo per risolvere questo problema?

risposta

41

Utilizzare una funzione per il secondo argomento per .replace() che restituisce la stringa con corrispondenza effettiva con i tag concatenati.

Provalo:http://jsfiddle.net/4sGLL/

reg = new RegExp(querystr, 'gi'); 
     // The str parameter references the matched string 
     // --------------------------------------v 
final_str = 'foo ' + result.replace(reg, function(str) {return '<b>'+str+'</b>'}); 
$('#' + id).html(final_str);​ 

JSFiddle Esempio con ingresso:https://jsfiddle.net/pawmbude/

+8

Il modo migliore per farlo anche se lo farei senza una funzione: 'result.replace (reg, '$ &')'. Non so però delle prestazioni, sembra solo più bello. – Joost

+0

la soluzione __perfect__ –

+0

neanch'io, ma dimentico sempre la sintassi 'function', quindi sono andato a cercare della documentazione. L'ho trovato per "incidente". – Joost

0

Faccio esattamente la stessa cosa.

È necessario effettuare una copia.

Memorizzo nel db una copia della stringa reale, in lettere minuscole.

Quindi eseguo una ricerca utilizzando una versione minuscola della stringa di query o un'espressione regexp senza distinzione tra maiuscole e minuscole.

Quindi utilizzare l'indice di inizio trovato risultante nella stringa principale, più la lunghezza della stringa di query, per evidenziare la stringa di query all'interno del risultato.

Non è possibile utilizzare la stringa di query nel risultato poiché il suo caso non è determinato. È necessario evidenziare una parte della stringa originale.

-1

.match() esegue caso di corrispondenza insensibile e restituisce un array di partite con il caso intatta.

var matches = str.match(queryString), 
    startHere = 0, 
    nextMatch, 
    resultStr ='', 
    qLength = queryString.length; 

for (var match in matches) { 
    nextMatch = str.substr(startHere).indexOf(match); 
    resultStr = resultStr + str.substr(startHere, nextMatch) + '<b>' + match + '</b>'; 
    startHere = nextMatch + qLength; 
} 
-1

Ho trovato un modo più semplice per raggiungerlo.L'espressione regolare JavaScript memorizza la stringa corrispondente. Questa funzione può essere utilizzata qui.

Ho modificato il codice un po '.

reg = new RegExp("("+querystr.trim()+")", 'gi'); 
final_str = 'foo ' + result.replace(reg, "<b>&1</b>"); 
$('#'+id).html(final_str); 
+0

puoi aggiungere qualche descrizione sulla differenza tra la tua soluzione e la risposta accettata? e l'utilità del ")"? – Mimouni

0

bei risultati con

function str_highlight_text(string, str_to_highlight){ 
    var reg = new RegExp(str_to_highlight, 'gi'); 
    return string.replace(reg, function(str) {return '<span style="background-color:#ffbf00;color:#fff;"><b>'+str+'</b></span>'}); 
} 

e più facile da ricordare ... thx a user113716: https://stackoverflow.com/a/3294644/2065594

0

Mentre le altre risposte finora sembrano semplici, non possono essere realmente utilizzati in molti casi reali in quanto non gestiscono l'escape di testo HTML e l'escaping di RegExp. Se si desidera evidenziare ogni possibile frammento, mentre sfuggire al testo in modo corretto, una funzione del genere sarebbe tornato tutti gli elementi si dovrebbe aggiungere alla tua casella di suggerimenti:

function highlightLabel(label, term) { 
    if (!term) return [ document.createTextNode(label) ] 
    const regex = new RegExp(term.replace(/[\\^$*+?.()|[\]{}]/g, '\\$&'), 'gi') 
    const result = [] 
    let left, match, right = label 
    while (match = right.match(regex)) { 
    const m = match[0], hl = document.createElement('b'), i = match.index 
    b.innerText = m 
    left = right.slice(0, i) 
    right = right.slice(i + m.length) 
    result.push(createTextNode(left), hl) 
    if (!right.length) return result 
    } 
    result.push(createTextNode(right)) 
    return result 
} 
1

ES6 versione

const highlight = (needle, haystack) => 
    haystack.replace(new RegExp(needle, 'gi'), str => `<strong>${str} 
</strong>`) 
Problemi correlati