2010-07-20 15 views
17

Tôi đang cố gắng viết "hộp tìm kiếm đề xuất" và tôi không thể tìm thấy giải pháp cho phép làm nổi bật chuỗi con bằng javascript.Javascript: làm nổi bật chuỗi con giữ trường hợp gốc nhưng tìm kiếm trong trường hợp chế độ không nhạy cảm

Ví dụ nếu tôi tìm kiếm "ca" Tôi tìm kiếm phía máy chủ trong một chế độ vô cảm trường hợp và tôi có kết quả như sau:

Calculator

lịch

ESCAPE

tôi sẽ muốn xem chuỗi tìm kiếm trong tất cả các từ trước, do đó kết quả phải là:

lculator

ca lendar

ES CA PE

Tôi đã thử với đoạn mã sau:

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

Nhưng rõ ràng theo cách này tôi mất trường hợp ban đầu!

Có cách nào để giải quyết vấn đề này không?

Trả lời

41

Sử dụng hàm cho đối số thứ hai cho .replace() trả về chuỗi được đối sánh thực tế với các thẻ được nối.

Hãy thử nó ra: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 Ví dụ với Input:https://jsfiddle.net/pawmbude/

+8

Cách tốt nhất để làm nó, mặc dù tôi sẽ làm điều đó mà không có một hàm: 'result.replace (reg, '$ &')'. Không biết về hiệu suất mặc dù, nó chỉ có vẻ đẹp hơn. – Joost

+0

__perfect solution__ –

+0

Tôi cũng vậy, nhưng tôi luôn quên cú pháp 'function' vì vậy tôi đã tìm kiếm một số tài liệu. Tôi thấy điều này bằng 'tai nạn'. – Joost

0

Tôi cũng làm điều tương tự.

Bạn cần tạo bản sao.

Tôi lưu trữ trong db một bản sao của chuỗi thực, trong tất cả các chữ thường.

Sau đó, tôi tìm kiếm bằng cách sử dụng phiên bản chữ thường của chuỗi truy vấn hoặc thực hiện regexp không phân biệt chữ hoa chữ thường.

Sau đó, sử dụng chỉ mục bắt đầu được tìm thấy trong chuỗi chính, cộng với độ dài của chuỗi truy vấn, để làm nổi bật chuỗi truy vấn trong kết quả.

Bạn không thể sử dụng chuỗi truy vấn trong kết quả do trường hợp của nó không được xác định. Bạn cần đánh dấu một phần của chuỗi gốc gốc.

-1

.match() thực hiện trường hợp phù hợp không nhạy cảm và trả về một mảng của các trận đấu với trường hợp còn nguyên vẹn.

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

Tôi đã tìm thấy cách dễ nhất để đạt được điều đó.Biểu thức chính quy JavaScript ghi nhớ chuỗi mà nó khớp. Có thể sử dụng tính năng này tại đây.

Tôi đã sửa đổi mã một chút.

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

bạn có thể thêm một số mô tả về sự khác biệt giữa giải pháp bạn và câu trả lời được chấp nhận không? và tiện ích của ")"? – Mimouni

0

kết quả tốt đẹp với

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

và dễ nhớ ... thx để user113716: https://stackoverflow.com/a/3294644/2065594

0

Trong khi câu trả lời khác cho đến nay dường như đơn giản, họ có thể không được thực sự sử dụng trong nhiều trường hợp thế giới thực khi họ không xử lý HTML thoát văn bản thích hợp và thoát khỏi RegExp. Nếu bạn muốn làm nổi bật mỗi đoạn có thể, trong khi thoát khỏi văn bản đúng cách, một chức năng như vậy sẽ trở lại tất cả các yếu tố mà bạn nên thêm vào hộp đề xuất của bạn:

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 phiên bản

const highlight = (needle, haystack) => 
    haystack.replace(new RegExp(needle, 'gi'), str => `<strong>${str} 
</strong>`) 
Các vấn đề liên quan