Вопрос по regex, replace, html – выделить слова в HTML с помощью регулярных выражений и JavaScript - почти там

0

Я пишу плагин jquery, который будет выполнять поиск на странице в стиле браузера. Мне нужно улучшить поиск, но я пока не хочу разбирать html.

На данный момент мой подход состоит в том, чтобы взять весь элемент DOM и все вложенные элементы и просто запустить регулярное выражение найти / заменить для данного термина. В замене я просто оберну промежуток вокруг совпадающего термина и буду использовать этот промежуток в качестве своего якоря для выделения, прокрутки и т. Д.It is vital that no characters inside any html tags are matched.

Это так близко, как я получил:

(?<=^|>)([^><].*?)(?=<|$)

Он делает очень хорошую работу по захвату всех персонажей, которыеnot в теге html, но у меня не получается понять, как вставить свой поисковый запрос.

Input: Any html element (this could be quite large, eg <body>)    
Search Term: 1 or more characters    
Replace Txt: <span class='highlight'>$1</span>

UPDATE

Следующее регулярное выражение делает то, что я хочу, когда я тестирую сhttp://gskinner.com/RegExr/...

Regex: (?<=^|>)(.*?)(SEARCH_STRING)(?=.*?<|$)
Replacement: $1<span class='highlight'>$2</span>

Однако у меня возникли проблемы с использованием его в моем JavaScript. С помощью следующего кода Chrome выдает ошибку «Неверное регулярное выражение: / (? & Lt; = ^ | & gt;) (.?)(Mary)(?=.? & lt; | $) /: недействительная группа ".

var origText = $('#'+opt.targetElements).data('origText');
var regx = new RegExp("(?<=^|>)(.*?)(" + $this.val() + ")(?=.*?<|$)", 'gi');
$('#'+opt.targetElements).each(function() {
   var text = origText.replace(regx, '$1<span class="' + opt.resultClass + '">$2</span>');
   $(this).html(text);
});

Это разбивает группу (? & Lt; = ^ | & gt;) - это что-то неуклюжее или разница в движках Regex?

UPDATE

Причина, по которой это регулярное выражение нарушает эту группу, заключается в том, что Javascript не поддерживает регулярные выражения. Для справки & amp; возможные решения:http://blog.stevenlevithan.com/archives/mimic-lookbehind-javascript.

Посмотри наmark.js как это может быть то, что вы ищете. dude
@ Правда: Спасибо за вашу заботу. Пожалуйста, воздержитесь. Я согласен с вашими заявлениями и принимаю вашу очевидную повестку дня. Мой вопрос, как я могу вставить поисковый термин в эту строку регулярного выражения? doub1ejack
У меня есть план, чтобы перейти к разбору html, но мне нужно быстрое подтверждение концепции, прежде чем я получу зеленый свет на это. doub1ejack
sigh Пожалуйста, воздержитесь от разбора HTML с RegEx, поскольку это будетdrive you insane, ИспользуйтеHTML parser вместо. Madara Uchiha♦
Это должно быть подтверждением вашей концепции, а не RegExp. Это решенная проблема, пожалуйста, не переусердствуйте с RegExp. Madara Uchiha♦

Ваш Ответ

1   ответ
0

text() method, Он вернет все символы в выбранном элементе DOM.

Для подхода DOM (документы дляNode interface): Запустить все дочерние узлы элемента. Если дочерний элемент является узлом элемента, запустите рекурсивно. Если это текстовый узел, выполните поиск по тексту (node.data) и если вы хотите что-то выделить / изменить, укоротите текст узла до найденной позиции и вставьте выделенный интервал с соответствующим текстом и другой текстовый узел для остальной части текста.

Пример кода (скорректированный, происхождениеВот):

(function iterate_node(node) {
    if (node.nodeType === 3) { // Node.TEXT_NODE
        var text = node.data,
            pos = text.search(/any regular expression/g), //indexOf also applicable
            length = 5; // or whatever you found
        if (pos > -1) {
            node.data = text.substr(0, pos); // split into a part before...
            var rest = document.createTextNode(text.substr(pos+length)); // a part after
            var highlight = document.createElement("span"); // and a part between
            highlight.className = "highlight";
            highlight.appendChild(document.createTextNode(text.substr(pos, length)));
            node.parentNode.insertBefore(rest, node.nextSibling); // insert after
            node.parentNode.insertBefore(highlight, node.nextSibling);
            iterate_node(rest); // maybe there are more matches
        }
    } else if (node.nodeType === 1) { // Node.ELEMENT_NODE
        for (var i = 0; i < node.childNodes.length; i++) {
            iterate_node(node.childNodes[i]); // run recursive on DOM
        }
    }
})(content); // any dom node

Там такжеhighlight.js, который может быть именно тем, что вы хотите.

Тогда вам может понадобитьсяnative DOM методы и изменения текстовых узлов.
Да, я уже закодировал различные итераторы текста-узла :) Слишком долго для комментария, расширил мой ответ.
Здорово. Сейчас я хорош, но когда я получу одобрение в этом проекте, я думаю, что сначала попробую этот подход. Используя метод jquery: contains (api.jquery.com/contains-selector/), я смогу найти условия поиска в DOM. Как только у меня появятся элементы, вам будет достаточно просто манипулировать .text () по мере необходимости. Спасибо Берги. doub1ejack
блин - говорил слишком рано. $ (# target *: Содержит («текст»)) хорошо выполняет поиск элементов, но возвращает содержащий элемент. Этот элемент содержит смесь контента, моего поискового запроса и других HTML. Использование .text () удаляет теги (неприемлемо), а .html () оставляет мне исходную проблему поиска смешанного контента & amp; разметка для поискового запроса. : содержит () сужает игровое поле, но проблема поиска / замены остается. @ Берджи, у тебя был какой-то особенный подход к DOM? doub1ejack
Я вижу, как .text () может использоваться для получения и замены текста элемента, но я не вижу, как можно использовать это для поиска / замены подмножества текста этого элемента. Пример: я хочу выделить только слова «и»; в длинном & lt; p & gt; элемент. Идеи? doub1ejack

Похожие вопросы