Надежный двухсторонний транслит
Здравствуйте!
Использую windows-1251, урлы на русском банерные сети не принимают. Ищу скрипт для перевода на лат для урл и обратно на рус для запросa в базе, без ошибок обратного перевода, конечно. Благодарю за любую помощь. Вал. |
В инете все есть давно :)
|
Цитата:
Надежного не нашел, а тех которые переводят "сходит -> shodit -> шодит" действительно много! |
Цитата:
Цитата:
|
dmitriymar, зачем же словарь? Есть ГОСТ 7.79-2000, который обеспечивает безошибочную двухстороннюю транслитерацию. Вот пример в лоб:
//Если с английского на русский, то передаём вторым параметром true. transliterate = ( function() { var rus = "щ ш ч ц ю я ё ж ъ ы э а б в г д е з и й к л м н о п р с т у ф х ь".split(/ +/g), eng = "shh sh ch cz yu ya yo zh `` y' e` a b v g d e z i j k l m n o p r s t u f x `".split(/ +/g) ; return function(text, engToRus) { var x; for(x = 0; x < rus.length; x++) { text = text.split(engToRus ? eng[x] : rus[x]).join(engToRus ? rus[x] : eng[x]); text = text.split(engToRus ? eng[x].toUpperCase() : rus[x].toUpperCase()).join(engToRus ? rus[x].toUpperCase() : eng[x].toUpperCase()); } return text; } } )(); var txt = "Съешь ещё этих мягких французских булок, да выпей же чаю!"; alert(transliterate(txt)); alert(transliterate(transliterate(txt), true)); |
Цитата:
Забыл сказать, :( в исходной строке могут быть латинские символы, которые должны транслироваться без изменения... |
Для преобразование в урл использую вот такую штучку
зачем преобразовывать обратно не совсем понял (я у себя в базе храню данные как оригинального названия для вывода на страницы так и урла для поиска нужного блока на вывод) использую эту функцию можно писать название в смешаном режиме (все возможные символы) и нужные будут преобразованы а ненужные удалены //Транслитерация кириллицы в URL function urlRusLat(str) { str = str.toLowerCase(); // все в нижний регистр var cyr2latChars = new Array( ['а', 'a'], ['б', 'b'], ['в', 'v'], ['г', 'g'], ['д', 'd'], ['е', 'e'], ['ё', 'yo'], ['ж', 'zh'], ['з', 'z'], ['и', 'i'], ['й', 'y'], ['к', 'k'], ['л', 'l'], ['м', 'm'], ['н', 'n'], ['о', 'o'], ['п', 'p'], ['р', 'r'], ['с', 's'], ['т', 't'], ['у', 'u'], ['ф', 'f'], ['х', 'h'], ['ц', 'c'], ['ч', 'ch'],['ш', 'sh'], ['щ', 'shch'], ['ъ', ''], ['ы', 'y'], ['ь', ''], ['э', 'e'], ['ю', 'yu'], ['я', 'ya'], ['А', 'A'], ['Б', 'B'], ['В', 'V'], ['Г', 'G'], ['Д', 'D'], ['Е', 'E'], ['Ё', 'YO'], ['Ж', 'ZH'], ['З', 'Z'], ['И', 'I'], ['Й', 'Y'], ['К', 'K'], ['Л', 'L'], ['М', 'M'], ['Н', 'N'], ['О', 'O'], ['П', 'P'], ['Р', 'R'], ['С', 'S'], ['Т', 'T'], ['У', 'U'], ['Ф', 'F'], ['Х', 'H'], ['Ц', 'C'], ['Ч', 'CH'], ['Ш', 'SH'], ['Щ', 'SHCH'], ['Ъ', ''], ['Ы', 'Y'], ['Ь', ''], ['Э', 'E'], ['Ю', 'YU'], ['Я', 'YA'], ['a', 'a'], ['b', 'b'], ['c', 'c'], ['d', 'd'], ['e', 'e'], ['f', 'f'], ['g', 'g'], ['h', 'h'], ['i', 'i'], ['j', 'j'], ['k', 'k'], ['l', 'l'], ['m', 'm'], ['n', 'n'], ['o', 'o'], ['p', 'p'], ['q', 'q'], ['r', 'r'], ['s', 's'], ['t', 't'], ['u', 'u'], ['v', 'v'], ['w', 'w'], ['x', 'x'], ['y', 'y'], ['z', 'z'], ['A', 'A'], ['B', 'B'], ['C', 'C'], ['D', 'D'],['E', 'E'], ['F', 'F'],['G', 'G'],['H', 'H'],['I', 'I'],['J', 'J'],['K', 'K'], ['L', 'L'], ['M', 'M'], ['N', 'N'], ['O', 'O'],['P', 'P'], ['Q', 'Q'],['R', 'R'],['S', 'S'],['T', 'T'],['U', 'U'],['V', 'V'], ['W', 'W'], ['X', 'X'], ['Y', 'Y'], ['Z', 'Z'], [' ', '_'],['0', '0'],['1', '1'],['2', '2'],['3', '3'], ['4', '4'],['5', '5'],['6', '6'],['7', '7'],['8', '8'],['9', '9'], ['-', '-'] ); var newStr = new String(); for (var i = 0; i < str.length; i++) { ch = str.charAt(i); var newCh = ''; for (var j = 0; j < cyr2latChars.length; j++) { if (ch == cyr2latChars[j][0]) { newCh = cyr2latChars[j][1]; } } // Если найдено совпадение, то добавляется соответствие, если нет - пустая строка newStr += newCh; } // Удаляем повторяющие знаки - Именно на них заменяются пробелы. // Так же удаляем символы перевода строки, но это наверное уже лишнее return newStr.replace(/[_]{2,}/gim, '_').replace(/\n/gim, ''); } |
vaalsh, может стоит тогда использовать encodeURIComponent?
var e = encodeURIComponent("Я вся такая строка with english letters."); var unE = decodeURIComponent(e); alert(e); alert(unE); |
GuardCat,
Не во всех ситуациях это подходит.Для тех же адресов для поисковиков подобная транслитерация не пройдет. А для внутреннего использования,если апострофы подходят , то почему нет |
Цитата:
самый простой вариант реализации такого: сделать словарь, куда автоматически будут записываться слова на латинице ещё перед конвертацией кир —> лат, а при обратной конвертации: сначала смотреть в этот словарь, если такого набора символов там нет — конвертировать. |
Всем Спасибо!
Буду использовать, с некоторой доработкой, 1-й скрипт.
Нашел возможность разделить рус/лат на заглавные/прописные. Еще раз, всем большое спасибо за вашу помощь! Вал. :thanks: |
Цитата:
Однозначная обратимость обеспечивается специфическим употреблением латинских букв h, у, с и символа `. Буквы h, у не означают сами по себе никаких кирилловских букв и употребляются только в буквосочетаниях. Для кириллических букв Ц и I установлены два варианта транслитерации. Ц передается либо латинской С, либо сочетанием CZ. Рекомендуется употреблять С перед буквами I, Е, Y, J, а в остальных случаях — CZ. |
Привет из 2017)
Вот мой вариант транслита Добавил возможность не переводить текст между двумя символами (например []) //Пример: function translit(text, engToRus, replace){ var rus = "щшчцюяёжъыэабвгдезийклмнопрстуфхь".split(""), eng = "shh sh ch cz yu ya yo zh `` y' e` a b v g d e z i j k l m n o p r s t u f x `".split(" ") for(var x = 0; x < rus.length; x++){ text = text.split(engToRus ? eng[x] : rus[x]).join(engToRus ? rus[x] : eng[x]); text = text.split(engToRus ? eng[x].toUpperCase() : rus[x].toUpperCase()).join(engToRus ? rus[x].toUpperCase() : eng[x].toUpperCase()); } if(replace){ r = replace.split(",") try{ pr = new RegExp("([^\\"+r[0]+"]+)(?=\\"+r[1]+")","g") text.match(pr).forEach(function(i){ text=text.split(r[0]+i+r[1]).join(translit(i, engToRus ? "" : true)) }) }catch(e){} } return text; } //с английского на русский alert(translit("text", true)) //тоже самое, но без перевода того, что написано в [ ] alert(translit("text [text]", true, "[,]")) //с русского на английский alert(translit("текст")) //тоже самое, но без перевода того, что написано в {[} {]} alert(translit("текст {[}текст{]}", true, "{[},{]}")) |
Занекропостим:)
Спасибо всем за идеи, подсократил и, возможно, ускорил код. Применяю для создания url из заголовка статьи в нашем издании: function translit(str) { str = str.toLowerCase().replace(/<.+>/, ' ').replace(/\s+/, ' '); var c = { 'а':'a', 'б':'b', 'в':'v', 'г':'g', 'д':'d', 'е':'e', 'ё':'jo', 'ж':'zh', 'з':'z', 'и':'i', 'й':'j', 'к':'k', 'л':'l', 'м':'m', 'н':'n', 'о':'o', 'п':'p', 'р':'r', 'с':'s', 'т':'t', 'у':'u', 'ф':'f', 'х':'h', 'ц':'c', 'ч':'ch', 'ш':'sh', 'щ':'shch', 'ъ':'', 'ы':'y', 'ь':'', 'э':'e', 'ю':'ju', 'я':'ja', ' ':'-', ';':'', ':':'', ',':'', '—':'-', '–':'-', '.':'', '«':'', '»':'', '"':'', "'":'', '@':'' } var newStr = new String(); for (var i = 0; i < str.length; i++) { ch = str.charAt(i); newStr += ch in c ? c[ch] : ch; } return newStr; } |
Часовой пояс GMT +3, время: 12:16. |