Javascript - 规范化重音的希腊字符

时间:2014-04-28 16:35:08

标签: javascript regex character normalization

我正在尝试对希腊文本应用某种规范化(使用小写,删除重音并用σ替换ς)。例如,我想“ἀντίθεσις”(希腊语polytonic)和“αντίθεσις”(现代希腊语)变成“αντιθεσισ”。 我浏览了unicode-table.com并写下了我应该做的字符替换。

Greek and Coptic (Range: 0370— 03FF) 
ΆΑά -> α
ΈΕέ -> ε
ΉΗή -> η
ΊΪΙίΐ -> ι
ΌΟό -> ο
ΎΫΥΰϋύ -> υ
ΏΩώ -> ω

Greek Extended (Range: 1F00— 1FFF)
ἀἁἂἃἄἅἆἇὰάᾀᾁᾂᾃᾄᾅᾆᾇᾰᾱᾲᾳᾴᾶᾷἈἉἊἋἌἍἎἏᾈᾉᾊᾋᾌᾍᾎᾏᾸᾹᾺΆᾼ -> α
ἐἑἒἓἔἕὲέἘἙἚἛἜἝῈΈ -> ε
ἠἡἢἣἤἥἦἧὴήᾐᾑᾒᾓᾔᾕᾖᾗῂῃῄῆῇἨἩἪἫἬἭἮἯᾘᾙᾚᾛᾜᾝᾞᾟῊΉῌ -> η
ἰἱἲἳἴἵἶἷὶίῐῑῒΐῖῗἸἹἺἻἼἽἾἿῘῙῚΊ -> ι
ὀὁὂὃὄὅὸόὈὉὊὋὌὍῸΌ -> ο
ὐὑὒὓὔὕὖὗὺύῠῡῢΰῦῧὙὛὝὟῨῩῪΎ -> υ
ὠὡὢὣὤὥὦὧὼώᾠᾡᾢᾣᾤᾥᾦᾧῲῳῴῶῷὨὩὪὫὬὭὮὯᾨᾩᾪᾫᾬᾭᾮᾯῺΏῼ -> ω
ῤῥῬ -> ρ

我想知道是否有一种聪明的方法来进行这些替换并避免逐个字符地检查字符串。

第一次尝试(感谢@Tyblitz)

normal = 'Αντίθετα με αυτό που θεωρεί η πλειοψηφία, το Lorem Ipsum δεν είναι απλά ένα τυχαίο κείμενο. Οι ρίζες του βρίσκονται σε ένα κείμενο Λατινικής λογοτεχνίας του 45 π.Χ., φτάνοντας την ηλικία του πάνω από 2000 έτη.';

pol = 'Μήγαρις ἔχω ἄλλο στὸ νοῦ μου πάρεξ ἐλευθερία καὶ γλώσσα;';

console.log(normalizeGreek(normal));
console.log(normalizePolytonicGreek(pol));

function normalizeGreek(text) {
    text = text.replace(/Ά|Α|ά/g, 'α')
        .replace(/Έ|Ε|έ/g, 'ε')
        .replace(/Ή|Η|ή/g, 'η')
        .replace(/Ί|Ϊ|Ι|ί|ΐ|ϊ/g, 'ι')
        .replace(/Ό|Ο|ό/g, 'ο')
        .replace(/Ύ|Ϋ|Υ|ύ|ΰ|ϋ/g, 'υ')
        .replace(/Ώ|Ω|ώ/g, 'ω')
        .replace(/Σ|ς/g, 'σ');
    return text;
}


function normalizePolytonicGreek(text) {
    text = text.replace(/Ά|Α|ά|ἀ|ἁ|ἂ|ἃ|ἄ|ἅ|ἆ|ἇ|ὰ|ά|ᾀ|ᾁ|ᾂ|ᾃ|ᾄ|ᾅ|ᾆ|ᾇ|ᾰ|ᾱ|ᾲ|ᾳ|ᾴ|ᾶ|ᾷ|Ἀ|Ἁ|Ἂ|Ἃ|Ἄ|Ἅ|Ἆ|Ἇ|ᾈ|ᾉ|ᾊ|ᾋ|ᾌ|ᾍ|ᾎ|ᾏ|Ᾰ|Ᾱ|Ὰ|Ά|ᾼ/g, 'α')
        .replace(/Έ|Ε|έ|ἐ|ἑ|ἒ|ἓ|ἔ|ἕ|ὲ|έ|Ἐ|Ἑ|Ἒ|Ἓ|Ἔ|Ἕ|Ὲ|Έ/g, 'ε')
        .replace(/Ή|Η|ή|ἠ|ἡ|ἢ|ἣ|ἤ|ἥ|ἦ|ἧ|ὴ|ή|ᾐ|ᾑ|ᾒ|ᾓ|ᾔ|ᾕ|ᾖ|ᾗ|ῂ|ῃ|ῄ|ῆ|ῇ|Ἠ|Ἡ|Ἢ|Ἣ|Ἤ|Ἥ|Ἦ|Ἧ|ᾘ|ᾙ|ᾚ|ᾛ|ᾜ|ᾝ|ᾞ|ᾟ|Ὴ|Ή|ῌ/g, 'η')
        .replace(/Ί|Ϊ|Ι|ί|ΐ|ἰ|ἱ|ἲ|ἳ|ἴ|ἵ|ἶ|ἷ|ὶ|ί|ῐ|ῑ|ῒ|ΐ|ῖ|ῗ|Ἰ|Ἱ|Ἲ|Ἳ|Ἴ|Ἵ|Ἶ|Ἷ|Ῐ|Ῑ|Ὶ|Ί/g, 'ι')
        .replace(/Ό|Ο|ό|ὀ|ὁ|ὂ|ὃ|ὄ|ὅ|ὸ|ό|Ὀ|Ὁ|Ὂ|Ὃ|Ὄ|Ὅ|Ὸ|Ό/g, 'ο')
        .replace(/Ύ|Ϋ|Υ|ΰ|ϋ|ύ|ὐ|ὑ|ὒ|ὓ|ὔ|ὕ|ὖ|ὗ|ὺ|ύ|ῠ|ῡ|ῢ|ΰ|ῦ|ῧ|Ὑ|Ὓ|Ὕ|Ὗ|Ῠ|Ῡ|Ὺ|Ύ/g, 'υ')
        .replace(/Ώ|Ω|ώ|ὠ|ὡ|ὢ|ὣ|ὤ|ὥ|ὦ|ὧ|ὼ|ώ|ᾠ|ᾡ|ᾢ|ᾣ|ᾤ|ᾥ|ᾦ|ᾧ|ῲ|ῳ|ῴ|ῶ|ῷ|Ὠ|Ὡ|Ὢ|Ὣ|Ὤ|Ὥ|Ὦ|Ὧ|ᾨ|ᾩ|ᾪ|ᾫ|ᾬ|ᾭ|ᾮ|ᾯ|Ὼ|Ώ|ῼ/g, 'ω')
        .replace(/ῤ|ῥ|Ῥ/g, 'ρ')
        .replace(/Σ|ς/g, 'σ');
    return text;
}

第二次尝试:

检查下面的answer,它使用String.prototype.normalize(),并阻止您保留列表中包含unicode表中所有希腊语重音字符。

3 个答案:

答案 0 :(得分:6)

我还找到了以下解决方案:String.prototype.normalize()

normal = 'Αντίθετα με αυτό που θεωρεί η πλειοψηφία, το Lorem Ipsum δεν είναι απλά ένα τυχαίο κείμενο. Οι ρίζες του βρίσκονται σε ένα κείμενο Λατινικής λογοτεχνίας του 45 π.Χ., φτάνοντας την ηλικία του πάνω από 2000 έτη.';

pol = 'Μήγαρις ἔχω ἄλλο στὸ νοῦ μου πάρεξ ἐλευθερία καὶ γλώσσα;';

console.log(normalizeGreek(normal));
console.log(normalizePolytonicGreek(pol));

function normalizeGreek(text) {
    return text.normalize('NFD').replace(/[\u0300-\u036f]/g, "");
}


function normalizePolytonicGreek(text) {
    return text.normalize('NFD').replace(/[\u0300-\u036f]/g, "");
}

工作原理+示例:

.normalize('NFD')内,重音字符被分解为:

使用以下方法删除这些标记很简单:.replace(/[\u0300-\u036f]/g, "")

a = "ἄ"
console.log(a);             // prints: ἄ
console.log(Array.from(a)); // prints: [ "ἄ" ]

b = a.normalize('NFD')
console.log(b);             // prints: ἄ 
console.log(Array.from(b)); // prints: [ "α", "̓", "́" ]

c = a.normalize('NFD').replace(/[\u0300-\u036f]/g, "")
console.log(c);             // prints: α
console.log(Array.from(c)); // prints: [ "α" ]

有趣的链接:

答案 1 :(得分:2)

您还可以使用npm库greek-utils,该库具有执行所需功能的方法,例如替换重音符号和其他变音符号。

对于现代希腊语:

var greekUtils = require('greek-utils');

var sanitized = greekUtils.sanitizeDiacritics('Αρνάκι άσπρο και παχύ');
console.log(sanitized); //Αρνακι ασπρο και παχυ

和古希腊语:

var greekUtils = require('greek-utils');

var sanitized = greekUtils.sanitizeDiacritics('Ἐξ οὗ καὶ δῆλον ὅτι οὐδεμία τῶν ἠθικῶν ἀρετῶν φύσει ἡμῖν ἐγγίνεται');
console.log(sanitized); //Εξ ου και δηλον οτι ουδεμια των ηθικων αρετων φυσει ημιν εγγινεται

答案 2 :(得分:1)

我认为你不能以另一种方式做到这一点,而不是通过检查每个字母,但这并没有使它更糟。

简单地将.replace函数链接起来:

result = string.replace(/Ά|Α|ά/g,'α')
  .replace(/Έ|Ε|έ/g,'ε')
  .replace(/Ή|Η|ή/g,'η');
// & so on...   

或者如果你宁愿循环它,你可能会做的事情,如果你有更多的字符要检查,并且哪个也更好的代码可维护性,将字符匹配存储在一个对象/数组的数组中。 例如。用一个对象:

var cvtValues =  [ /* from = chars to convert; to = conversion output */
  {from:['Ά','Α','ά'], to: 'α'}
  {from:['Έ','Ε','έ'], to: 'ε'}
  {from:['Ή','Η','ή'], to: 'η'}];
/* loop over all from-to containers */
for ( var i = 0; i < cvtValues.length; i++ ) {
  /* loop over all characters in the 'from' array & replace them with 'to' value*/
  for ( var x = 0; x < cvtValues[i].from.length; x++ ) {
    string = string.replace(new RegExp(cvtValues[i].from[x],'g'), cvtValues[i].to);
    /* You could assign this to another variable, eg. result if you wated */
  }
}