Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > Помогите решить проблему с транслитом


Автор: fleetboss 13.4.2010, 14:03
Добрый день.
У меня возникла проблема с транслитом текста, все работает на ура, но как сделать чтобы он html теги не переводил? Как в коде дописать чтобы он все что в <теге> не переводил? ну или хотябы сделать &nbsp; код впереди смайлика и в конце или еще как-то...
Код

var map_en = new Array('s`h','S`h','S`H','s`Х','sh`','Sh`','SH`',"'o",'yo',"'O",'Yo','YO','zh','w','Zh','ZH','W','ch','Ch','CH','sh','Sh','SH','e`','E`',"'u",'yu',"'U",'Yu',"YU","'a",'ya',"'A",'Ya','YA','a','A','b','B','v','V','g','G','d','D','e','E','z','Z','i','I','j','J','k','K','l','L','m','M','n','N','o','O','p','P','r','R','s','S','t','T','u','U','f','F','h','H','c','C','`','y','Y',"'")
var map_ru = new Array('Сх','СХ','сХ','щ','Щ','Щ','ё','ё','Ё','Ё','Ё','ж','ж','Ж','Ж','Ж','ч','Ч','Ч','ш','Ш','Ш','э','Э','ю','ю','Ю','Ю','Ю','я','я','Я','Я','Я','а','А','б','Б','в','В','г','Г','д','Д','е','Е','з','З','и','И','й','Й','к','К','л','Л','м','М','н','Н','о','О','п','П','р','Р','с','С','т','Т','у','У','ф','Ф','х','Х','ц','Ц','ъ','ы','Ы','ь')

var msg = "Soobwenie, kotoroe nado perevesti <img src=i/smiles/23.gif> prodolzenie soobwenija";

var exploded = Msg.split("|");
Msg = exploded[exploded.length-1];
for (var i = 0; i <map_en.length; ++i)
while (Msg.indexOf (map_en[i]) >= 0)
Msg = Msg.replace (map_en[i], map_ru[i]);
exploded[exploded.length-1] = Msg;
Msg = exploded.join("|");

Автор: нуп 13.4.2010, 14:12
Счетчик сделай. Открыл "<" count++, закрыл ">" count--. Если count = 0 переводи. Как то так !  smile 

Автор: fleetboss 13.4.2010, 14:22
Цитата(нуп @ 13.4.2010,  14:12)
Счетчик сделай. Открыл "<" count++, закрыл ">" count--. Если count = 0 переводи. Как то так !  smile

бредятина... нужно чтобы сообщение всегда транслировалось, только чтобы код смайлика не транлировался... надо как-то в коде написать чтобы он после < и до > код не транлировал  smile   smile 

Автор: нуп 13.4.2010, 14:46
Цитата(fleetboss @  13.4.2010,  14:22 Найти цитируемый пост)
бредятина... нужно чтобы сообщение всегда транслировалось, только чтобы код смайлика не транлировался... надо как-то в коде написать чтобы он после < и до > код не транлировал  smile   smile 

сам бредятина, сначала попробуй, потом говори  smile 

Автор: fleetboss 13.4.2010, 14:57
напиши пример кода своего

Автор: patap 14.4.2010, 14:09
Вот вроде как че-то набросал тут, не могу сказать что это самое рациональное решение, но вроде как работает

Основная идея в том, что мы временно заменяем все смайлы уникальной маской из цифр, затем делаем транслит и меняем маски обратно

Код

<script>
  function trans() {
    var map_en = new Array('s`h','S`h','S`H','s`Х','sh`','Sh`','SH`',"'o",'yo',"'O",'Yo','YO','zh','w','Zh','ZH','W','ch','Ch','CH','sh',
         'Sh','SH','e`','E`',"'u",'yu',"'U",'Yu',"YU","'a",'ya',"'A",'Ya','YA','a','A','b','B','v','V','g','G','d','D','e','E','z','Z',
         'i','I','j','J','k','K','l','L','m','M','n','N','o','O','p','P','r','R','s','S','t','T','u','U','f','F','h','H','c','C','`','y','Y',"'");
    var map_ru = new Array('Сх','СХ','сХ','щ','Щ','Щ','ё','ё','Ё','Ё','Ё','ж','ж','Ж','Ж','Ж','ч','Ч','Ч','ш','Ш','Ш','э','Э','ю','ю','Ю','Ю','Ю','я','я','Я','Я','Я','а','А','б','Б',
         'в','В','г','Г','д','Д','е','Е','з','З','и','И','й','Й','к','К','л','Л','м','М','н','Н','о','О','п','П','р','Р','с','С','т','Т','у','У','ф','Ф','х','Х','ц','Ц','ъ','ы','Ы','ь');
    
    var str = "Soobwenie, kotoroe nado<img src=i/smiles/25.gif> perevesti <img src=i/smiles/23.gif> prodolzenie soobwe<img src=i/smiles/21.gif>nijaf qwe rqwer qwer qwe ";
    var strLen = str.length;
    
   // находим все смайлы и записываем их в массив
    var smileReg = /<img.*?>/g;
    var smilesTemp = new Array();
    var smiles = new Array();   
    while ((smilesTemp = smileReg.exec(str)) != null) {
      smiles.push(smilesTemp[0]);
    }
    
    // создаем пары "маска" и "реальное значение" записываем в массив, тут же заменяем теги со смайлами на маски
    var imgMask = new Array();
    for (var i = 0; i < smiles.length; i++) {
      var mask = generateMask();
      str = str.replace(smiles[i], mask);
      imgMask.push(new Array(mask, smiles[i]));
    }
    
    // делаем транслит, к стати проверь свои массивы на соответствие, а то оно как-то странновато работает. Или у тебя бок или у меня, 
    // но я массивы с твоими символами не проверял
    for (i = 0; i < map_en.length; i++) {
      var exp = eval('/'+map_en[i]+'/gm');
      str = str.replace(exp, map_ru[i]);
    }
    
    // заменяем маски на реальные теги со смайлами
    for (i = 0; i < imgMask.length; i++) {
      str = str.replace(imgMask[i][0], imgMask[i][1]);
    }
    
    alert(str);
    
  }
  
  // генерирует маску
  function generateMask() {
    var food = '012345678901234567890123456789';
    var mask = '';
    var min_random = 0;
    var size = 12;
    var max_random = food.length - 1;
    var range = max_random - min_random;
    
    while (size != 0) {
      mask += food[Math.floor(Math.random() * range) + min_random];
      size--;
    }
    return mask;
  }
  
</script>

<input type="button" onclick="trans()">


если что не ясно - спрашивай

Автор: fleetboss 23.4.2010, 13:31
зачем нужен? var strLen = str.length; если это нигде в коде не указывается
смайлик он переводит как undefined только русскими буквами

"testovoe soobwenie  //006 blablabla"

переводит в:

"ТЕСТОВОЕ СООБЖЕНИЕ УНДЕФИНЕДУНДЕФИНЕДУНДЕФИНЕДУНДЕФИНЕДУНДЕФИНЕДУНДЕФИНЕДУНДЕФИНЕДУНДЕФИНЕДУНДЕФИНЕДУНДЕФИНЕДУНДЕФИНЕДУНДЕФИНЕД БЛАБЛАБЛА"

Автор: patap 27.4.2010, 09:50
var strLen - это мусор


да, действительно в ИЕ глючит

поменяй строку
Код

var food = '012345678901234567890123456789';


на 
Код

var food = new Array(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9);


и вроде должно заработать. И маповые массивы у тебя не соответствуют друг-другу

Автор: SelenIT 27.4.2010, 11:06
А зачем нам теги руками парсить, когда у нас целый парсер браузера под боком?
Код

function trans(node) {
    var map_en = new Array('s`h','S`h','S`H','s`Х','sh`','Sh`','SH`',"'o",'yo',"'O",'Yo','YO',
'zh','w','Zh','ZH','W','ch','Ch','CH','sh','Sh','SH','e`','E`',"'u",'yu',"'U",'Yu',"YU",
"'a",'ya',"'A",'Ya','YA','a','A','b','B','v','V','g','G','d','D','e','E','z','Z','i','I',
'j','J','k','K','l','L','m','M','n','N','o','O','p','P','r','R','s','S','t','T','u','U',
'f','F','h','H','c','C','`','y','Y',"'");
    var map_ru = new Array('Сх', 'СХ', 'сХ', 'щ',  'щ',  'Щ',  'Щ',  'ё','ё','Ё','Ё','Ё',
'ж','ж','Ж','Ж','Ж','ч','Ч','Ч','ш','Ш','Ш','э','Э','ю','ю','Ю','Ю','Ю',
'я','я','Я','Я','Я','а','А','б','Б','в','В','г','Г','д','Д','е','Е','з','З','и','И',
'й','Й','к','К','л','Л','м','М','н','Н','о','О','п','П','р','Р','с','С','т','Т','у','У',
'ф','Ф','х','Х','ц','Ц','ъ','ы','Ы','ь');
    if (node.nodeType == 3) { // текстовые ноды переводим
        for (var i=0; map_en[i]; i++) {
            node.nodeValue = node.nodeValue.split(map_en[i]).join(map_ru[i]);
        }
    }
    else if (node.nodeType == 1) { // теги обходим рекурсивно, ища текстовые ноды
        for (var i=0, part; part = node.childNodes[i]; i++) {
            trans(part);
        }        
    }
}

// заносим текст во вспомогательный DOM-контейнер
var tmpDOMnode = document.createElement('div');
tmpDOMnode.innerHTML = "Soobsh`enie, <span><i>kotoroe</i> <b>nado</b> perevesti</span> <img src=i/smiles/23.gif> prodolzhenie soobsh`eniya";

// и транслитерируем по кускам нашей супер-мега-функцией
trans(tmpDOMnode);

alert(tmpDOMnode.innerHTML);

Автор: ksnk 27.4.2010, 11:12
SelenIT, тег A какбы совсем даже не текстовый, а транслитерировать его очень даже надо..., так что все равно получится парсер, только по тегам  smile 

Автор: SelenIT 27.4.2010, 11:31
ksnk, но текстовое содержимое у него ведь есть;). Оно и переводится, по идее. А что, в IE проблемы?

Автор: ksnk 27.4.2010, 12:05
SelenIT, Хм... вообще-то все верно, и в IE вплоть до 6 версии все в порядке... Что-то я не то сказал smile извиняюсь...

Добавлено через 3 минуты и 50 секунд
patap, кстати, вот таким образом можно заменять теги на placeholder'ы и потом после издевательств - возвращать обратно.
Код

   function keyOf(obj,val){
       for(a in obj){ if (obj[a]==val) return a;}
       return null; 
    }

...

    function translit(){
       var store={},currentTAG=1;
   // заменяем все теги и записываем их в массив
       str = str.replace(/<script.*?\/script>|<style.*\/style>|<.*?>/ig,function(e){
            if(!store[e]) 
                store[e]=currentTAG++;
            return '@@'+store[e]+'@@';
       })

    // делаем транслит...
        ...

       retun str.replace(/@@(\d+)@@/g,function(e,e1){
            return keyOf(store,e1)||'';
       })
    }
    

Автор: patap 27.4.2010, 12:16
ksnk, га, интересно и проще чем у меня). Я конечно у себя в коде накролесил... smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)