Javascript: выделение подстроки с сохранением исходного регистра, но поиск в режиме без учета регистра - PullRequest
26 голосов
/ 21 июля 2010

Я пытаюсь написать «окно поиска предложений» и не могу найти решение, которое позволяет выделить подстроку с использованием javascript, сохраняя исходный регистр.

Например, если я ищу «ca», я выполняю поиск на стороне сервера в нечувствительном к регистру режиме и получаю следующие результаты:

Калькулятор

календарь

ESCAPE

Я хотел бы просмотреть строку поиска во всех предыдущих словах, поэтому результат должен быть:

Ca lculator

ч lendar

* * ES тысяча двадцать-один * * СА тысяча двадцать два РЕ

Я пытался с помощью следующего кода:

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

Но, очевидно, таким образом я теряю оригинальную коробку!

Есть ли способ решить эту проблему?

Ответы [ 9 ]

55 голосов
/ 21 июля 2010

Используйте функцию для второго аргумента для .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/

6 голосов
/ 06 декабря 2017

ES6 версия

const highlight = (needle, haystack) =>
  haystack.replace(new RegExp(needle, 'gi'), str => `<strong>${str}
</strong>`)
1 голос
/ 23 марта 2018

Не совсем идеально, так как он заменяет все на более низкий символ:

let ߐ = document.body
function check(_ૐ){
_ૐ_ = new RegExp(_ૐ, "ig") 
ߐ.innerHTML=ߐ.innerHTML.replace(_ૐ_,"<b>"+_ૐ+"</b>")
}

check('ca')
Calculator

calendar

ESCAPE

Cardan de voiture cassé
0 голосов
/ 10 сентября 2018

Выделение поискового термина и привязки к первому вхождению - Начало

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
}

Выделение поискового термина и привязки к первому вхождению - Конец

0 голосов
/ 20 июня 2017

Хотя остальные ответы пока кажутся простыми, они не могут быть реально использованы во многих реальных случаях, поскольку они не обрабатывают правильный текстовый 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
    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
}
0 голосов
/ 06 мая 2017

хороших результатов с

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

и их легче запомнить ... спасибо пользователю113716: https://stackoverflow.com/a/3294644/2065594

0 голосов
/ 15 июля 2016

Я нашел самый простой способ добиться этого.Регулярное выражение JavaScript запоминает соответствующую ему строку.Эту функцию можно использовать здесь.

Я немного изменил код.

reg = new RegExp("("+querystr.trim()+")", 'gi');
final_str = 'foo ' + result.replace(reg, "<b>&1</b>");
$('#'+id).html(final_str);
0 голосов
/ 21 июля 2010

.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;
}
0 голосов
/ 21 июля 2010

Я делаю то же самое.

Вам нужно сделать копию.

Я храню в БД копию реальной строки, все строчные.

Затем я выполняю поиск с использованием строчной версии строки запроса или выполняю регулярное выражение без учета регистра.

Затем используйте результирующий найденный начальный индекс в основной строке плюс длину строки запроса, чтобы выделить строку запроса в результате.

Вы не можете использовать строку запроса в результате, так как ее регистр не определен. Вам нужно выделить часть оригинальной строки.

...