在JavaScript中将Hangul Jamo转换为Hangul音节

时间:2017-02-27 05:35:29

标签: javascript unicode

我正在尝试以编程方式创建韩语句子,但要正确地这样做意味着我需要一种方法来确定哪个Hangul Jamo unicode字符组成每个Hangul Syllable unicode字符。更具体地说,我想收集Hangul Jamo字符的集合,并弄清楚如何将它们转换为Hangul Syllable字符。简单地连接字符串是行不通的,我查看了代码点值,看看Hangul Jamo和组合Hangul音节的代码点之间是否有明显的关系,但我没有看到。例如,天真地添加代码点不会得到正确的答案:

console.log(('ㄱ'.codePointAt(0) + 'ㅏ'.codePointAt(0)) === '가'.codePointAt(0));

它不会记录true,这在查看Hangul JamoHangul Syllables的Unicode图表时也是不言而喻的。到目前为止,我还没有在搜索中找到答案,但必须有一种方法可以以编程方式将部分转换为整个音节,对吧?

2 个答案:

答案 0 :(得分:3)

形成有效韩语音节的所有jamo序列都以Unicode中的预组合字符存在。此外,所有这些预先组合的字符都对jamo序列进行了规范分解,这意味着规范化形式C中的任何文本都将具有那些预先组合的字符,而不是jamo序列。

因此,简单地对由jamo组成的字符串进行规范化将导致尽可能多的预组合音节。这可以使用s.normalize("NFC")的JavaScript完成。

如果您不关心拥有jamo序列或预先组合的音节,但只关心比较相等的结果,那么您可以将字符串规范化为标准化形式(C或D),只要您同时具有相同的形式。

同样相关,Unicode FAQ on Korean有一个列表,其中规范化表格C将包含jamo而不是音节:

  

如果文本是NFD,那么它只包含Jamo。如果是在NFC中   (或非标准化),大多数文本将是Hangul音节。但是,Jamo   可能在某些情况下发生:

     

(a)孤立的Jamo
  (b)1933年以前的拼写韩语文本
  (c)现代不完整的音节(例如没有主要辅音的音节   用于词典和语法书籍)
  (d)用于更多的音节   一些方言忠实的语音表达

     

在后一种情况下,有两种可能性。如果L或V是   古代的Jamo,然后整个音节将在Jamo。如果两者都是   现代的Jamo,但T是古老的,那么音节就是   由两个字符的序列表示:单个代码点   LV,接着是T的代码点:< LV,T>

     

这与拉丁文的情况类似。 NFC形式的A +坟墓+   变音符号是< A-grave,umlaut> :部分是预先组合的,剩下的是   不

答案 1 :(得分:2)

我找到了答案on Wikipedia。按照该字符表的链接,但这里是使用的公式:

  

要在Unicode中查找Hangul音节,您可以应用简单的公式。公式和表格如下:   [{(初始)×588} + {(内侧)×28} +(最终)] + 44032

Here's an example of a really crappy random Korean sentence generator I threw together on JSFiddle。我使用结束字符的值(下面的最终randFin值)来确定单词的最后一个音节是以元音还是辅音结尾。这决定了在最终(几乎肯定无法理解)句子中出现的粒子的形式。它使用getRandomKWord方法中的unicode公式:

var getRandomInt = function(n, o) {
  var min = Math.ceil(n);
  var max = Math.floor(o);
  return Math.floor(Math.random() * (max - min)) + min;
};

var getRandomKWord = function() {
  var word = '';
  var num = getRandomInt(1, 3);

  for (var i = 0; i < num; i++) {
  	var randInit = getRandomInt(0, 19) * 588;
    var randMed = getRandomInt(0, 21) * 28;
    var randFin = getRandomInt(0, 28);
    var hangulFormula = randInit + randMed + randFin + 44032;

  	word = word + String.fromCodePoint(hangulFormula);
  }
  return { word: word, final: randFin };
};

var title = document.getElementById('title');

var subject = getRandomKWord();
var object = getRandomKWord();  // don't use 'object' as a variable name
var verb = getRandomKWord();

var subParticle = subject.final ? '는' : '은';
var objParticle = object.final ? '를' : '을';

var text = subject.word +
	subParticle +
  object.word +
  objParticle +
  verb.word +
  '습니다.';

title.innerText = text;
<h1 id='title'></h1>