Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   replace исключая в атрибутах тегов (https://javascript.ru/forum/misc/46220-replace-isklyuchaya-v-atributakh-tegov.html)

NapalmRain 02.04.2014 12:04

replace исключая в атрибутах тегов
 
Доброго всем времени суток!
Есть небольшая задачка, сделать подсветку синтаксиса кода на странице.
Есть массив зарезервированных слов, которые должны подсвечиваться в тексте.
скрипт проходит по этому массиву примерно так:
for (var k in words) {
text = replaceAll(text, words[k]);
}

Внутри функции replaceAll тоже всё просто
tempString = string.replace(new RegExp(word, 'g'), '<span class="codeword">'+word+'</span>');

Так вот тут возникает проблемка, если среди зарезервированных слов встречается, к примеру слово class, то оно учитывается и внутри тегов и тег
<span class="codeword">
превращается в
<span <span class="codeword">class="codeword">

Прошу подсказать, как реализовать замену всего этого добра исключая теги. То есть смотреть текст только между тегами.
Я понимаю, что нужно составить регулярное выражение, наверное, что-то из цикла:
replace(/>([^"]+)</g, '>$1<');
только вот мне куда-то сюда ещё нужно вместить значение моей переменной word.
И тогда ещё встанет вопрос, а как же быть, если тегов нет вовсе...
Я честно говоря, плохо разбираюсь в регулярных выражениях в принципе. Прошу подсказки.

Заранее благодарю!

Octane 02.04.2014 12:37

Не люблю сложные регулярки, поэтому, если текст небольшой, я бы сначала нашел все теги

наверное такое выражение подойдет
/<(?:(?:[^>]|\n)*)>/
и выполнил бы для них escape, заменил нужные слова, а потом unescape

рони 02.04.2014 12:37

NapalmRain,
jQuery highlight plugin — поиск и подсветка слов в тексте

NapalmRain 02.04.2014 13:53

Цитата:

Сообщение от рони (Сообщение 305574)

За ссылку спасибо!
Обязательно посмотрю,почитаю.

Но хочется именно для себя сделать нечто своё. Это не какая-то конкретная задача, которую мне поставили и я пытаюсь её выполнить. Это просто задача от самого себя для саморазвития.

NapalmRain 02.04.2014 13:53

Цитата:

Сообщение от Octane (Сообщение 305573)
Не люблю сложные регулярки, поэтому, если текст небольшой, я бы сначала нашел все теги

наверное такое выражение подойдет
/<(?:(?:[^>]|\n)*)>/
и выполнил бы для них escape, заменил нужные слова, а потом unescape

Благодарю! Попробую посмотреть в данном направлении.

danik.js 02.04.2014 16:37

NapalmRain, если замену нужно делать в живом DOM'е, то вместо использования innerHTML можно пройтись по всем текстовым нодам и сделать замену. Это конечно будеть работать чуть медленней, зато не надо париться со сложными регулярками.

рони 02.04.2014 16:40

Цитата:

Сообщение от danik.js
пройтись по всем текстовым нодам и сделать замену. Это конечно будеть работать чуть медленней, зато не надо париться

плагин по ссылке выше именно так и делает, но вы туда неходите )))

NapalmRain 02.04.2014 17:09

Цитата:

Сообщение от рони (Сообщение 305640)
плагин по ссылке выше именно так и делает, но вы туда неходите )))

Ну как я уже сказал, задачей изначально было решить вопрос самостоятельно.

Учусь я. А учиться лучше всего получается на решении ошибок.

Результат вообще получился интересным и совсем не по тому пути, по которому пошёл изначально.

Не откажусь от комментариев:
(function( $ ){
	var phpWords = ['public', 'private', 'static', 'function', 'class', 'if', 'switch', 'case', 'break', 'echo', 'die', 'else', 'require_once', 'include', '$'];
	
	var init = function (object, arrayOfWords) {
		var words = [];
		for (var k in arrayOfWords) {
			words[arrayOfWords[k]] = arrayOfWords[k];
		}
		var include = object.html();
		var lines = include.split('\n');
		var newInclude = null;
		var wordsInLine;
		newInclude = '<table>';
		newInclude += '<tr class="codeLines"><td class="linesNubmbers">';
		for (var key in lines) {	
			num = parseInt(key)+1;
			newInclude += num+'<br>';
		}
		newInclude += '</td>';
		newInclude += '<td class="codeBlock">';
		for (var key in lines) {
			wordsInLine = lines[key].split(" ");
			for (var k in wordsInLine) {
				if (typeof(words[wordsInLine[k].trim()])!=='undefined') {
					wordsInLine[k] = '<span class="codeword">'+wordsInLine[k]+'</span>';
				}
			}
			lines[key] = wordsInLine.join(' ');
			
			newInclude += lines[key]+'<br>';
		}
		newInclude += '</td></tr>';
		newInclude += '</table>';
		object.html(newInclude);
	}
	
	$.fn.testsintax = function(language) {
		switch (language) {
			case 'php':
				init($(this), phpWords);
				break;
			case 'delphi':
				init($(this), delphiWords);
				break;
			case 'javascript': break;
			case 'java': break;
			case 'code': break;
			case 'c#': break;
	}
  };

})( jQuery );

$('document').ready(function() {
	$('#php').testsintax('php');
});

Опустил из кода всё, что касается конкретных языков, комментариев и прочих деталей. Только подсветка слов, заранее указанных в массиве.


Часовой пояс GMT +3, время: 13:53.