Не воспринимается кириллица.
Добрый день. Помогите,пожалуйста, советом. Пишу расширение для хрома, которое бы заменяло слова на сайтах на те, которые прописаны у меня в файле.
В файле 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();
})();
|
Вопрос в следующем: что нужно прописать дополнительно, чтобы "ру на ру" так же менялось?
|
Цитата:
|
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);
})();
|
Цитата:
new RegExp('(^|\\s)' + original_escaped + '($|\\s)')
|
MashaDo,
Пожалуйста, отформатируйте свой код! Для этого его можно заключить в специальные теги: js/css/html и т.п., например: [html run] ... минимальный код страницы с вашей проблемой [/html] О том, как вставить в сообщение исполняемый javascript и html-код, а также о дополнительных возможностях форматирования - читайте http://javascript.ru/formatting. |
не работает так( хром делает RegExp('(^|\\s)' + original_escaped + '($|\\s)')
как ошибку синтаксиса. Замена слов не происходит. |
спасибо, что сказали)не знала о такой возможности.
|
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_]. |
MashaDo,
regex = new RegExp(`(^|\\s|[.,])${original_escaped}($|\\s|[.,])`, 'gi');
if (v.match(regex)) {
v = v.replace(regex, `$1${replacements[original]}$2`);
matchFound = true;
}
|
рони, а чем не устроило моё решение, или почему такое ограниченное понимание границы слова?
|
Цитата:
Цитата:
|
Цитата:
|
Malleys,
ссылку на сахар не подскажите? |
В учебнике Ильи Кантора написано: https://learn.javascript.ru/regexp-c...anitsa-slova-b (это магия , не объясняется откуда взялось \b, почему всё-таки только граница английских слов)
https://en.wikipedia.org/wiki/Regula...racter_classes |
Malleys,
как узнать про поддержку Позитивный просмотр назад (?<=\W) ? |
|
Malleys,
спасибо за помощь! |
Malleys,
regex = new RegExp(`(?:^|(?<=\\W))${original_escaped}(?:(?=\\W)|$)`, "gi");
|
Коды, которые приведены в конце, работают, но не совсем так как надо...
Может есть код, который бы позволял просто не учитывать синтаксис? |
Цитата:
|
Цитата:
regex = new RegExp(original_escaped, "gi"); |
у меня в словаре, слова не только в именительном падеже, но и в других, а так же во множественном.
2 примера: "валик" : "подушка", "валики" : "подушки", и "валик" : "кутуз", "валики" : "кутузы". В первом случае текст отображается как "подушкаи малярные". Во втором " кутузи малярные". В первом случае он так отображается, так как видит, что в словаре есть слова "валик" и заменяет его, не обращая внимания, что так же в словаре содержится слова "валики", которое должно быть приоритетным.. Может можно как-то исправить отображение? |
Цитата:
regex = new RegExp(`(?:^|(?<=[^a-zёа-я0-9_])(?=[a-zёа-я0-9_]))${original_escaped}(?:(?<=[a-zёа-я0-9_])(?=[^a-zёа-я0-9_])|$)`, "gi");
|
спасибо большое))
странно...пробовала утром, работало примерно так же, как я описала выше. Сейчас решила попробовать вновь - работает идеально. Спасибо) |
Цитата:
|
| Часовой пояс GMT +3, время: 22:58. |