Javascript-форум (https://javascript.ru/forum/)
-   Opera, Safari и др. (https://javascript.ru/forum/css-html-browser/)
-   -   Не воспринимается кириллица. (https://javascript.ru/forum/css-html-browser/77629-ne-vosprinimaetsya-kirillica.html)

MashaDo 29.05.2019 15:57

Не воспринимается кириллица.
 
Добрый день. Помогите,пожалуйста, советом. Пишу расширение для хрома, которое бы заменяло слова на сайтах на те, которые прописаны у меня в файле.
В файле dictionaries содержатся слова: 1 колонка - что заменить, 2 колонка -на что заменить. Пример:
var dictionary={
"replacements": {
"TEX1" : "arb",
"Opera" : "Не опера",
"Маша" : "Мария" и т.д.
Так вот, с нахождением англ слов и заменой на англ - расширение справляется. С нахождением англ слов и заменой на ру - тоже. Но "Маша" : "Мария" он заменять отказывается, как и другие слова "ру на ру".

Привожу пример кода background.HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
  <!-- Тег meta для указания кодировки -->

<meta http-equiv="content-type" content="text/html; charset=utf-8" />

   <head>
    <title>Background Page</title>
    <script src="dictionaries/original.js"></script>
    <script src="background.js"></script>
  </head>
  <body>
  </body>
</html>

___
dictionaries/original.js - тут лежат слова для замены с заменой.
__

файл background.js" показан ниже:

(function() {

    var ONE_DAY = 1000 * 60 * 60 * 24;

    var KEY_LAST_CHANGED_AT = 'lastChangedAt';
    var KEY_OPTIONS = 'options';
    var KEY_PAUSED = 'paused';

    var _alreadyQueued = false;

    function now() {
        return new Date().getTime();
    }

    function checkForRandomSwap() {
        var lastChangedAt, pollTimeout;
        var options = JSON.parse(localStorage.getItem(KEY_OPTIONS));

        if(options && options.checkDaily) {
            lastChangedAt = parseInt(localStorage.getItem(KEY_LAST_CHANGED_AT), 10);

            //не вносились изменения
            if(isNaN(lastChangedAt) || lastChangedAt + ONE_DAY < now()) {
                var pause = Math.random() > 0.5; // Flip a coin!
                lastChangedAt = setPaused(pause);
            }

            // Set up the next check.
            if(!_alreadyQueued) {
                pollTimeout = (lastChangedAt + ONE_DAY) - now();

                setTimeout(function() {
                    _alreadyQueued = false;
                    checkForRandomSwap();
                }, pollTimeout);
                
                _alreadyQueued = true;
            }
        }
    }

    function updateBadge(paused) {
        var badgeText = paused ? "OFF" : "";
        chrome.browserAction.setBadgeText( { text: badgeText } );
    }

    function isPaused() {
        return (localStorage.getItem(KEY_PAUSED) == 'true');
    }

    function setPaused(paused) {
        var lastChangedAt = now();

        localStorage.setItem(KEY_PAUSED, paused);
        chrome.storage.sync.set( { 'paused': paused } );
        updateBadge(paused);

        localStorage.setItem(KEY_LAST_CHANGED_AT, lastChangedAt);
        return lastChangedAt;
    }

    function togglePause(tab) {
        setPaused(!isPaused());

        // Reload the current tab.
        chrome.tabs.update(tab.id, {url: tab.url});
    }

    function getExcluded() {
        var opts = JSON.parse(localStorage.getItem(KEY_OPTIONS));
        return opts ? opts['excluded'] : [];
    }

    function onMessage(request, sender, sendResponse) {
        var requestId = request.id;

        if(requestId == 'isPaused?') {
            // TODO: Convert to boolean.
            sendResponse({value: isPaused()});
        }
        else if(requestId == 'getExcluded') {
            sendResponse({value: getExcluded()});
        }
        else if(requestId == 'setOptions') {
            localStorage.setItem(KEY_OPTIONS, request.options);
        }
        else if(requestId == 'getDictionary') {
            sendResponse(dictionary);
        }
    }

    chrome.browserAction.onClicked.addListener(togglePause);
    chrome.extension.onRequest.addListener(onMessage);



    updateBadge(isPaused());

    checkForRandomSwap();

})();

MashaDo 29.05.2019 15:59

Вопрос в следующем: что нужно прописать дополнительно, чтобы "ру на ру" так же менялось?

Malleys 29.05.2019 16:30

Цитата:

Сообщение от MashaDo
Вопрос в следующем: что нужно прописать дополнительно, чтобы "ру на ру" так же менялось?

А где у вас, собственно говоря, эта замена происходит?

MashaDo 29.05.2019 16:31

function() {
	var _self = this;
	var _dictionary;

	function getDictionary(callback) {
		chrome.extension.sendRequest({id: "getDictionary"}, function(response) {
			_dictionary = response; // Store the dictionary for later use аа
			callback.apply(_self, arguments);
		});
	}

	function handleText(textNode) {
		var replacements = _dictionary.replacements;
    var expressions = _dictionary.expressions;
		var v = textNode.nodeValue;
		var matchFound = false;

		var regex, original;

		//text replacements
		for(original in replacements) {
			original_escaped = original;

			regex_for_question_mark = /\?/g
			regex_for_period = /\./g

			original_escaped = original_escaped.replace(regex_for_question_mark, "\\?");
			original_escaped = original_escaped.replace(regex_for_period, "\\.");

			regex = new RegExp('\\b' + original_escaped + '\\b', "gi");
			if (v.match(regex)) {
				v = v.replace(regex, replacements[original]);
				matchFound = true;
			}

		}

		// regex replacements
		for(original in expressions) {
			regex = new RegExp(original, "g");
			if (v.match(regex)) {
				v = v.replace(regex, expressions[original]);
				matchFound = true;
			}

		}

		// Меняем только в случае изменения текста
		if (matchFound) {
			textNode.nodeValue = v;
		}

	}
	function walk(node) {

		//  не удалять. связан с осн узлом

		var child, next;

		switch(node.nodeType) {
			case 1:  // Element
			case 9:  // Document
			case 11: // Document fragment
				child = node.firstChild;
				while(child) {
					next = child.nextSibling;
					walk(child);
					child = next;
				}
				break;
			case 3: // Text 
				handleText(node);
				break;
		}
	}


	var running = true;


	function work() {

		running = true;

	
		walk(document.body);

	
		running = false;
	}



	chrome.extension.sendRequest({id: 'isPaused?'}, function(response) {
		var isPaused = response.value;

	
		if(isPaused) {
        return;
    }

    chrome.extension.sendRequest({id: 'getExcluded'}, function (r2) {

        var ex = r2.value;
        for (x in ex) {
            if (window.location.href.indexOf(ex[x]) != -1) {
                return;
            }
        }

        getDictionary(function() {
            work();
        });
    });

	});



	var timeout = null;

	document.addEventListener('DOMSubtreeModified', function(){
		if (running) {
			return;
		}

		if (timeout) {
			clearTimeout(timeout);
		}

		timeout = setTimeout(work, 500);
	}, false);

})();

рони 29.05.2019 16:41

Цитата:

Сообщение от MashaDo
new RegExp('\\b' + original_escaped + '\\b'

new RegExp('(^|\\s)' + original_escaped + '($|\\s)')

рони 29.05.2019 16:49

MashaDo,
Пожалуйста, отформатируйте свой код!

Для этого его можно заключить в специальные теги: js/css/html и т.п., например:
[html run]
... минимальный код страницы с вашей проблемой
[/html]

О том, как вставить в сообщение исполняемый javascript и html-код, а также о дополнительных возможностях форматирования - читайте http://javascript.ru/formatting.

MashaDo 29.05.2019 16:52

не работает так( хром делает RegExp('(^|\\s)' + original_escaped + '($|\\s)')
как ошибку синтаксиса. Замена слов не происходит.

MashaDo 29.05.2019 16:59

спасибо, что сказали)не знала о такой возможности.

рони 29.05.2019 17:09

MashaDo,
regex = new RegExp('(^|\\s)' + original_escaped + '($|\\s)', 'gi');

MashaDo 29.05.2019 17:15

так тоже не работает..

MashaDo 29.05.2019 17:18

прошу прощения)не верно исправила код)
заработало. Спасибо большое!

Malleys 29.05.2019 17:22

Цитата:

Сообщение от рони (Сообщение 508492)
MashaDo,
regex = new RegExp('(^|\\s)' + original_escaped + '($|\\s)', 'gi');

А как насчёт «Маша! Маша, как дела?»? Или такое не надо заменять?

Вот изменённое определение \b (напоминаю для рони, что это синтаксический сахар для (?<=\W)(?=\w)|(?<=\w)(?=\W))

Так что правильный вариант такой:

MashaDo,

regex = new RegExp(`(?:^|(?<=\\W)(?=\\S))${original_escaped}(?:(?<=\\S)(?=\\W)|$)`, "gi");


или можно расширить кириллицей...
regex = new RegExp(`(?:^|(?<=[^a-zёа-я0-9_])(?=[a-zёа-я0-9_]))${original_escaped}(?:(?<=[a-zёа-я0-9_])(?=[^a-zёа-я0-9_])|$)`, "gi");


\b не работает с кириллицей, поскольку в его определении указано \w, а оно соответственно является синтаксическим сахаром только для [A-Za-z0-9_].

рони 29.05.2019 17:32

MashaDo,
regex = new RegExp(`(^|\\s|[.,])${original_escaped}($|\\s|[.,])`, 'gi');
			if (v.match(regex)) {
				v = v.replace(regex, `$1${replacements[original]}$2`);
				matchFound = true;
			}

Malleys 29.05.2019 17:42

рони, а чем не устроило моё решение, или почему такое ограниченное понимание границы слова?

рони 29.05.2019 18:05

Цитата:

Сообщение от Malleys
а чем не устроило моё решение,

1. не видел 2. не знаю этот сахар, не могу использовать, не уверен в поддержке метода
Цитата:

Сообщение от Malleys
почему такое ограниченное понимание границы слова?

если нужно можно добавить кавычки, двоеточие и прочие знаки [., сюда];

Malleys 29.05.2019 18:27

Цитата:

Сообщение от рони
если нужно можно добавить кавычки, двоеточие и прочие знаки [., сюда];

Что значит нужно? Это необходимо! Написали решение, которое всё время нужно исправлять. И в принципе оно у вас плохо поддерживается, так как легче сказать, что в слово входит, чем что в слово не должно входить!

рони 29.05.2019 18:33

Malleys,
ссылку на сахар не подскажите?

Malleys 29.05.2019 18:48

В учебнике Ильи Кантора написано: https://learn.javascript.ru/regexp-c...anitsa-slova-b (это магия , не объясняется откуда взялось \b, почему всё-таки только граница английских слов)

https://en.wikipedia.org/wiki/Regula...racter_classes

рони 29.05.2019 18:53

Malleys,
как узнать про поддержку Позитивный просмотр назад (?<=\W) ?

Malleys 29.05.2019 19:02

https://caniuse.com/#feat=js-regexp-lookbehind
https://kangax.github.io/compat-tabl...ind_Assertions (включая node.js)

рони 29.05.2019 19:09

Malleys,
спасибо за помощь!

рони 29.05.2019 19:25

Malleys,
предлагаю такой вариант
regex = new RegExp(`(?:^|(?<=\\W))${original_escaped}(?:(?=\\W)|$)`, "gi");

MashaDo 30.05.2019 14:05

Коды, которые приведены в конце, работают, но не совсем так как надо...
Может есть код, который бы позволял просто не учитывать синтаксис?

Malleys 30.05.2019 14:10

Цитата:

Сообщение от MashaDo
Может есть код, который бы позволял просто не учитывать синтаксис?

Какой синтаксис не учитывать? Что вы имеете в виду?

рони 30.05.2019 14:37

Цитата:

Сообщение от MashaDo
Может есть код, который бы позволял просто не учитывать синтаксис?

так?
regex = new RegExp(original_escaped, "gi");

MashaDo 30.05.2019 15:24

у меня в словаре, слова не только в именительном падеже, но и в других, а так же во множественном.
2 примера:
"валик" : "подушка",
"валики" : "подушки",
и

"валик" : "кутуз",
"валики" : "кутузы".

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

Может можно как-то исправить отображение?

Malleys 30.05.2019 15:41

Цитата:

Сообщение от MashaDo
Может можно как-то исправить отображение?

Это разве не работает, которое я вчера сделал?
regex = new RegExp(`(?:^|(?<=[^a-zёа-я0-9_])(?=[a-zёа-я0-9_]))${original_escaped}(?:(?<=[a-zёа-я0-9_])(?=[^a-zёа-я0-9_])|$)`, "gi");

MashaDo 30.05.2019 15:56

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

рони 30.05.2019 16:11

Цитата:

Сообщение от Malleys
Это разве не работает, которое я вчера сделал?

работает, без кирилицы RegExp недостаточный. пост #25


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