私はこのUnicode文字列を持っています: Ааа́Ббб́Ввв́Г㥴Дд
そして、文字で分割したい。今、すべての文字の真実をループしようとすると、次のような結果が得られます。
A a a ' Б ...
この文字列を chars: に適切に分割する方法はあります А а а́
か?
私はこのUnicode文字列を持っています: Ааа́Ббб́Ввв́Г㥴Дд
そして、文字で分割したい。今、すべての文字の真実をループしようとすると、次のような結果が得られます。
A a a ' Б ...
この文字列を chars: に適切に分割する方法はあります А а а́
か?
これを適切に行うために必要なのは、UAX 29で定義されているように、書記素クラスターの境界を計算するためのアルゴリズムです。残念ながら、これには、どの文字がどのクラスのメンバーであるかを Unicode Character Database から知る必要があり、JavaScript はその情報を利用できません (*)。そのため、スクリプトに UCD のコピーを含める必要があり、かなりかさばります。
ラテン語またはキリル文字で使用される基本的なアクセントのみを気にする必要がある場合の代替手段は、Combining Diacritical Marks ブロック (U+0300-U+036F) のみを使用することです。これは他の言語や記号では失敗しますが、やりたいことには十分かもしれません。
function findGraphemesNotVeryWell(s) {
var re= /.[\u0300-\u036F]*/g;
var match, matches= [];
while (match= re.exec(s))
matches.push(match[0]);
return matches;
}
findGraphemesNotVeryWell('Ааа́Ббб́Ввв́Г㥴Дд');
["А", "а", "а́", "Б", "б", "б́", "В", "в", "в́", "Г", "г", "Ґ", "ґ", "Д", "д"]
(*: ブラウザーに文字列をレンダリングさせ、その中の選択位置を測定することで情報を抽出する方法があるかもしれません... しかし、クロスブラウザーで動作させるのは非常に面倒で難しいでしょう.)
このパッケージが役立つかもしれません: https://www.npmjs.com/package/runes
const runes = require('runes')
const example = 'Emoji '
example.split('') // ["E", "m", "o", "j", "i", " ", "�", "�"]
runes(example) // ["E", "m", "o", "j", "i", " ", ""]
Node.js からデータのチャンクを消費する必要があるアプリケーションを作成している場合は、stream
パイプを介しutf8-stream
てこれを防ぐことができます。
あなたの文字列の問題は、ブラウザで表示されたときにのみ記号文字に結合されるサロゲート ペア ("a" "́) です。あなたの場合、前の文字に \u0301 を付ければ十分ですが、これは決して一般的な解決策。
var a="Ааа́Ббб́Ввв́Г㥴Дд",
i =0,
chars=[];
while(a.charAt(i)) {
if (a.charAt(i+1) == "\u0301") {
chars.push(a.charAt(i++)+a.charAt(i++));
} else {
chars.push(a.charAt(i++));}}
この問題を明確にするには、Mathias Bynens のブログ投稿を参照してください。