2

I have the function for translate cirrilic characters to latin, and also some characters. Also, I need to translate '.' to '-', but if I add '.':'-' to the ru-object, the numbers are translated as undefined . Escaping a point \. don't help. I can add in ru-object each number to fix, but I want to understand, why this is happening.

 let ru = {
            'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd',
            'е': 'e', 'ё': 'e', 'ж': 'j', 'з': 'z', 'и': 'i', 'й': 'j',
            'к': 'k', 'л': 'l', 'м': 'm', 'н': 'n', 'о': 'o',
            'п': 'p', 'р': 'r', 'с': 's', 'т': 't', 'у': 'u',
            'ф': 'f', 'х': 'h', 'ц': 'c', 'ч': 'ch', 'ш': 'sh',
            'щ': 'shch', 'ъ': '',  'ы': 'y', 'ь': '', 
            'э': 'e', 'ю': 'u', 'я': 'ya', ' ': '-', '/': '-', '«':'', '»':'', '.':'-'          
        };
  
    function trans(str){
        str1 = str.toLowerCase();
        let result = str1.replace(
          new RegExp(Object.keys(ru).join('|'), 'g'),
          function(match) {
            return ru[match];
          }
        );                          
        return result;                          
    }   
  
  alert( trans('150собственников.ру')); //undefinedundefinedundefinedsobstvennikov-ru

https://jsfiddle.net/Nata_Hamster/49bnLmqd/

user43436
  • 31
  • 3

1 Answers1

1

You need to keep the ru array as is, but when building the regex from keys, escape the dot.

You can use

let ru = {
  'а': 'a',  'б': 'b',  'в': 'v',  'г': 'g',  'д': 'd',  'е': 'e',  'ё': 'e',  'ж': 'j',
  'з': 'z',  'и': 'i',  'й': 'j',  'к': 'k',  'л': 'l',  'м': 'm',  'н': 'n',  'о': 'o',
  'п': 'p',  'р': 'r',  'с': 's',  'т': 't',  'у': 'u',  'ф': 'f',  'х': 'h',  'ц': 'c',
  'ч': 'ch',  'ш': 'sh',  'щ': 'shch',  'ъ': '',  'ы': 'y',  'ь': '',  'э': 'e',  'ю': 'u',
  'я': 'ya',  ' ': '-',  '/': '-',  '«': '',  '»': '',  '.': '-'
};

function trans(str) {
  const regex = new RegExp(Object.keys(ru).map(x => x.replace('.', '\\.')).join('|'), 'g');
  let result = str.toLowerCase().replace(regex, function(match) {
    return ru[match[0]];
  });
  return result;
}

console.log(trans('150собственников.ру'));

If you want to use any chars, make sure you simply use the right escaping function, see Is there a RegExp.escape function in JavaScript?. Then, you will just need to replace .map(x=>x.replace('.','\\.')) with .map(x=>x.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')).

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563