2010-07-20 12 views
17

Próbuję napisać "pole wyszukiwania sugestii" i nie mogę znaleźć rozwiązania, które pozwala podświetlić podciąg z javascriptem zachowując oryginalny przypadek.Javascript: podświetl podciągi zachowując oryginalny przypadek, ale wyszukiwanie w trybie niewrażliwym na wielkość liter

Na przykład jeśli wyszukać "ca" szukam po stronie serwera w przypadku trybu niewrażliwego i mam następujące wyniki:

Kalkulator

kalendarz

ESCAPE

bym jak wyświetlić ciąg wyszukiwania we wszystkich poprzednich słowach, więc wynik powinien być:

Ca lculator

ca lendar

ES CA PE

próbowałem z następującego kodu:

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

Ale oczywiście w ten sposób tracę oryginalną obudowę!

Czy istnieje sposób rozwiązania tego problemu?

Odpowiedz

41

Użyj funkcji dla drugiego argumentu dla .replace(), która zwraca faktyczny dopasowany ciąg z połączonymi znacznikami.

Spróbuj: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 przykład z wejściem:https://jsfiddle.net/pawmbude/

+8

Najlepszy sposób to zrobić to, chociaż zrobiłbym to bez funkcji: 'result.replace (reg, '$ &')'. Nie wiem jednak o wydajności, po prostu wygląda na ładniej. – Joost

+0

the__perfect solution__ –

+0

Ja też nie, ale zawsze zapominam o składni funkcji, więc poszedłem poszukać dokumentacji. Znalazłem to przez "wypadek". – Joost

0

Robię dokładnie to samo.

Musisz wykonać kopię.

Przechowuję w db kopię prawdziwego ciągu we wszystkich małych literach.

Następnie wyszukuję za pomocą małej litery w łańcuchu zapytania lub w przypadku wyrażenia regularnego bez rozróżniania wielkości liter.

Następnie użyj wynikowego znalezionego indeksu początkowego w ciągu głównym, a także długość ciągu zapytania, aby podświetlić ciąg zapytania w wyniku.

Nie można użyć ciągu zapytania w wyniku, ponieważ jego wielkość nie jest określona. Musisz podświetlić fragment oryginalnego ciągu.

-1

.match() wykonuje przypadku niewrażliwe dopasowanie i zwraca tablicę dopasowania w przypadku zmian.

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

Znalazłem najprostszy sposób, aby to osiągnąć.Wyrażenie regularne JavaScript zapamiętuje dopasowany ciąg znaków. Z tej funkcji można korzystać tutaj.

Trochę zmodyfikowałem kod.

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

Czy możesz dodać opis różnicy między twoim rozwiązaniem a zaakceptowaną odpowiedzią? i użyteczność ")"? – Mimouni

0

ładne wyniki z

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>'}); 
} 

i łatwiejsze do zapamiętania ... thx do user113716: https://stackoverflow.com/a/3294644/2065594

0

Podczas gdy inne odpowiedzi do tej pory wydawać się proste, nie mogą być rzeczywiście wykorzystane w wielu rzeczywistych przypadkach, ponieważ nie radzą sobie z prawidłowym wychwytywaniem kodu HTML i wyskakiwaniem RegExp. Jeśli chcesz wyróżnić każdą możliwą fragment, podczas ucieczki tekst poprawnie, funkcja tak zwróciłby wszystkie elementy należy dodać do swojej skrzynki Sugestie:

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 wersji

const highlight = (needle, haystack) => 
    haystack.replace(new RegExp(needle, 'gi'), str => `<strong>${str} 
</strong>`) 
Powiązane problemy