Помогите написать регулярное выражение, которое будет окружать определенный текст тегами <strong>, только если тег <strong>отсутствует - PullRequest
2 голосов
/ 17 мая 2010

У меня есть несколько постов на сайте; все эти сообщения являются чатами этого типа:

AD: Эй!
BC: Что случилось?
AD: Ничего
БК: Хорошо

Они помечены как простые абзацы, окруженные <p> тегами.

Используя функцию замены javascript, я хочу, чтобы все экземпляры "AD" в начале диалога (то есть все экземпляры "AD" в начале строки, за которыми следовал ":"), были окружены <strong> тегов, но только если экземпляр еще не окружен тегом <strong>.

Какое регулярное выражение я должен использовать для достижения этой цели? Я пытаюсь сделать то, что этот советует против?

Код, который я использую, выглядит следующим образом:

var posts = document.getElementsByClassName('entry-content');

for (var i = 0; i < posts.length; i++) {
    posts[i].innerHTML = posts[i].innerHTML.replace(/some regex here/,
    'replaced content here');
}

Ответы [ 3 ]

1 голос
/ 17 мая 2010

Если AD: всегда находится в начале строки, то должно работать следующее регулярное выражение, используя переключатель m:

.replace(/^AD:/gm, "<strong>AD:</strong>");

Вам не нужно проверять наличие <strong>, потому что ^ будет соответствовать началу строки, а регулярное выражение будет совпадать только в том случае, если последовательность символов, следующая за началом строки, равна AD: .

Вы не идете против рекомендации «Не используйте регулярные выражения для разбора HTML», потому что вы не анализируете HTML, вы просто заменяете строку другой строкой.

Альтернативой регулярному выражению будет работать с диапазонами , создавая диапазон, выделяя текст, а затем используя execCommand , чтобы сделать текст жирным. Тем не менее, я думаю, что это будет гораздо сложнее, и вы, вероятно, столкнетесь с различиями в реализации браузеров. Путь регулярного выражения должно быть достаточно. <Ч /> После просмотра вашего комментария следующее регулярное выражение будет работать нормально:

.replace(/<(p|br)>AD:/gm, "<$1><strong>AD:</strong>");
1 голос
/ 17 мая 2010

Использование регулярных выражений на innerHTML не надежно и может привести к проблемам. Правильный способ сделать это - утомительный процесс, но гораздо более надежный.

Е.Г.

for (var i = 0, l = posts.length; i < l; i++) {

    findAndReplaceInDOM(posts[i], /^AD:/g, function(match, node){

        // Make sure current node does note have a <strong> as a parent
        if (node.parentNode.nodeName.toLowerCase() === 'strong') {
            return false;
        }

        // Create and return new <strong>
        var s = document.createElement('strong');
        s.appendChild(document.createTextNode(match[0]));
        return s;

    });

}

И функция findAndReplaceInDOM:

function findAndReplaceInDOM(node, regex, replaceFn) {

    // Note: regex MUST have global flag
    if (!regex || !regex.global || typeof replaceFn !== 'function') {
        return;
    }

    var start, end, match, parent, leftNode,
        rightNode, replacementNode, text,
        d = document;

    // Loop through all childNodes of "node"
    if (node = node && node.firstChild) do {

        if (node.nodeType === 1) {

            // Regular element, recurse:
            findAndReplaceInDOM(node, regex, replaceFn);

        } else if (node.nodeType === 3) {

            // Text node, introspect

            parent = node.parentNode;
            text = node.data;

            regex.lastIndex = 0;

            while (match = regex.exec(text)) {

                replacementNode = replaceFn(match, node);

                if (!replacementNode) {
                    continue;
                }

                end = regex.lastIndex;
                start = end - match[0].length;

                // Effectively split node up into three parts:
                // leftSideOfReplacement + REPLACEMENT + rightSideOfReplacement

                leftNode = d.createTextNode( text.substring(0, start) );
                rightNode = d.createTextNode( text.substring(end) );

                parent.insertBefore(leftNode, node);
                parent.insertBefore(replacementNode, node);
                parent.insertBefore(rightNode, node);

                // Remove original node from document
                parent.removeChild(node);

            }

        }
    } while (node = node.nextSibling);

}
1 голос
/ 17 мая 2010

Не проще ли установить для свойства class или style найденного абзаца значение text-weight: bold или класс, который делает примерно то же самое? Таким образом, вам не придется беспокоиться о добавлении тегов или поиске существующих тегов. Возможно, будет лучше, если вам не нужно заменять строки.

Если вы действительно хотите добавить сильные теги, я бы предложил использовать функции DOM, чтобы найти дочерние узлы вашего абзаца, которые , а если вы не найдете один, добавьте его и переместите оригинал ) childNode абзаца в него.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...