Javascript: выделить подстроку, сохраняющую исходный регистр, но поиск в случае нечувствительного режима
Я пытаюсь написать "окно поиска предложений" и не могу найти решение, позволяющее выделить подстроку с помощью javascript, сохраняя исходный регистр.
Например, если я ищу "ca
", я выполняю поиск на стороне сервера в нечувствительном к регистру режиме и получаю следующие результаты:
Калькулятор
календарь
ПОБЕГ
Я хотел бы просмотреть строку поиска во всех предыдущих словах, поэтому результат должен быть следующим:
Ca lculator
ча lendar
ES CA РЕ
Я попытался с помощью следующего кода:
var reg = new RegExp(querystr, 'gi');
var final_str = 'foo ' + result.replace(reg, '<b>'+querystr+'</b>');
$('#'+id).html(final_str);
Но, очевидно, таким образом я теряю оригинальное дело!
Есть ли способ решить эту проблему?
Ответы
Ответ 1
Используйте функцию для второго аргумента для .replace()
, которая возвращает фактическую совпавшую строку с объединенными тегами.
Попробуйте: 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 с вводом: https://jsfiddle.net/pawmbude/
Ответ 2
Версия ES6
const highlight = (needle, haystack) =>
haystack.replace(new RegExp(needle, 'gi'), str => `<strong>${str}
</strong>`)
Ответ 3
Хотя другие ответы пока кажутся простыми, они не могут быть реально использованы во многих реальных случаях, поскольку они не обрабатывают надлежащий текстовый экранирование HTML и экранирование RegExp. Если вы хотите выделить все возможные фрагменты, при правильном экранировании текста, подобная функция вернет все элементы, которые вы должны добавить в окно предложений:
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
hl.innerText = m
left = right.slice(0, i)
right = right.slice(i + m.length)
result.push(document.createTextNode(left), hl)
if (!right.length) return result
}
result.push(document.createTextNode(right))
return result
}
Ответ 4
Не совсем идеально, так как он заменяет все на более низкий символ:
let ߐ = document.body
function check(_ૐ){
_ૐ_ = new RegExp(_ૐ, "ig")
ߐ.innerHTML=ߐ.innerHTML.replace(_ૐ_,"<b>"+_ૐ+"</b>")
}
check('ca')
Calculator
calendar
ESCAPE
Cardan de voiture cassé
Ответ 5
Я делаю то же самое.
Вам нужно сделать копию.
Я храню в db копию реальной строки во всех нижних регистрах.
Затем я выполняю поиск с использованием строчной строки запроса или безрежимного регулярного выражения.
Затем используйте полученный в результате найденный начальный индекс в основной строке плюс длину строки запроса, чтобы выделить строку запроса в результате.
Вы не можете использовать строку запроса в результате, так как ее случай не определен. Вам нужно выделить часть строки оригинал.
Ответ 6
хорошие результаты с
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>'});
}
и легче запомнить...
спасибо to user113716: fooobar.com/questions/318524/...
Ответ 7
Выделите поисковый запрос и привязку к первому вхождению - начало
function highlightSearchText(searchText) {
var innerHTML = document.documentElement.innerHTML;
var replaceString = '<mark>'+searchText+'</mark>';
var newInnerHtml = this.replaceAll(innerHTML, searchText, replaceString);
document.documentElement.innerHTML = newInnerHtml;
var elmnt = document.documentElement.getElementsByTagName('mark')[0]
elmnt.scrollIntoView();
}
function replaceAll(str, querystr, replace) {
var reg = new RegExp(querystr, 'gi');
var final_str = str.replace(reg, function(str) {return '<mark>'+str+'</mark>'});
return final_str
}
Выделите поисковый запрос и привязку к первому вхождению - конец
Ответ 8
.match()
выполняет нечувствительность к регистру и возвращает массив совпадений с неповрежденным случаем.
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;
}
Ответ 9
Я нашел самый простой способ добиться этого. Регулярное выражение JavaScript запоминает строку, которую она сопоставила. Эта функция может быть использована здесь.
Я немного изменил код.
reg = new RegExp("("+querystr.trim()+")", 'gi');
final_str = 'foo ' + result.replace(reg, "<b>&1</b>");
$('#'+id).html(final_str);