Last active
February 22, 2023 09:31
-
-
Save HackyDev/a4c8922acbd5371a79bbd221959dc8b9 to your computer and use it in GitHub Desktop.
Транслитератор кирилического алфавита в латинский и обратно для использования в url
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class RuEnUrlTransliterator { | |
constructor () { | |
this.init() | |
} | |
private ruEn: Record<string, string> = {} | |
private enRu: Record<string, string> = { | |
a: 'а', | |
b: 'б', | |
v: 'в', | |
g: 'г', | |
d: 'д', | |
e: 'е', | |
'.yo': 'ё', | |
j: 'ж', | |
z: 'з', | |
i: 'и', | |
'.ii': 'й', | |
k: 'к', | |
l: 'л', | |
m: 'м', | |
n: 'н', | |
o: 'о', | |
p: 'п', | |
r: 'р', | |
s: 'с', | |
t: 'т', | |
u: 'у', | |
f: 'ф', | |
h: 'х', | |
c: 'ц', | |
'.ch': 'ч', | |
'.sh': 'ш', | |
'.sj': 'щ', | |
'.mz': 'ь', | |
'.tz': 'ъ', | |
y: 'ы', | |
'.eh': 'э', | |
'.yu': 'ю', | |
'.ya': 'я', | |
'.cm': ',', | |
'-': '-', | |
'~': '~', | |
0: '0', | |
1: '1', | |
2: '2', | |
3: '3', | |
4: '4', | |
5: '5', | |
6: '6', | |
7: '7', | |
8: '8', | |
9: '9' | |
} | |
private ruEnSpecial: Record<string, string> = { | |
' ': '_' | |
} | |
private enRuSpecial: Record<string, string> = { | |
_: ' ' | |
} | |
private init () { | |
for (const key in this.enRu) { | |
const value = this.enRu[key] | |
const keyUpperCased = key.toUpperCase() | |
const valueUpperCased = value.toUpperCase() | |
this.ruEn[value] = key | |
this.ruEn[valueUpperCased] = keyUpperCased | |
this.enRu[keyUpperCased] = valueUpperCased | |
} | |
} | |
public ruToEn (str: string): string { | |
let out = '' | |
if (!this.isRuValid(str)) { | |
console.error('Invalid value:', str) | |
throw new Error('valueInvalid') | |
} | |
for (let i = 0; i < str.length; i++) { | |
const char = this.ruEn[str[i]] || this.ruEnSpecial[str[i]] | |
if (char === undefined) throw new Error('unknownChar') | |
out += char | |
} | |
return out | |
} | |
public enToRu (str: string): string { | |
if (!this.isEnValid(str)) { | |
console.error('Invalid value:', str) | |
throw new Error('valueInvalid') | |
} | |
let out = '' | |
for (let i = 0; i < str.length; i++) { | |
let char = this.enRu[str[i]] || this.enRuSpecial[str[i]] | |
if (char === undefined) { | |
char = this.enRu[str[i] + str[i + 1] + str[i + 2]] | |
if (char) { | |
i += 2 | |
} | |
} | |
if (char === undefined) { | |
throw new Error('unknownChar') | |
} | |
out += char | |
} | |
return out | |
} | |
public isRuValid (value: string): boolean { | |
return /^[а-яА-ЯёЁ0-9 ,~-]*$/.test(value) | |
} | |
public isEnValid (value: string): boolean { | |
return /^[a-zA-Z0-9._~-]*$/.test(value) | |
} | |
} | |
/* | |
const transliterator = new RuEnUrlTransliterator() | |
const ruOriginal = 'Моторное масло' | |
const en = transliterator.ruToEn(ruOriginal) | |
const ruTransliterated = transliterator.enToRu(en) // "Motornoe_maslo" | |
console.log(ruTransliterated === ruOriginal) // true | |
*/ | |
const transliterator = new RuEnUrlTransliterator() | |
export { transliterator } | |
export default RuEnUrlTransliterator |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment