[JavaScript] Unicode を含む文字列を一部切り出すなら unicode-substring を使うべき
- 2019 11/7
- カテゴリー : 未分類
- JavaScript
- コメントを書く
JavaScript や Node.js で Unicode を含む文字列を一部切り出したい場合 substring ではなく unicode-substring を使うべきという事例とサンプルコードをご紹介します。
背景 substring + encodeURI = URIError: malformed URI sequence
String.prototype.substring() で一部を切り出した文字列を encodeURI メソッドの引数に渡すと、Unicode 上位サロゲートのみが残った文字列だった場合 URIError: malformed URI sequence エラーが発生します。
- String.prototype.substring() – JavaScript | MDN
- URIError: malformed URI sequence – JavaScript | MDN
- Unicode – Wikipedia
substring の代わりに unicode-substring を使おう
同僚のシニアエンジニアから「Unicode の仕様は複雑なので String.prototype.substring() で扱わない方が良い」というアドバイスを頂きました。
参考: FAQ – UTF-8, UTF-16, UTF-32 & BOM
unicode-substring
String.prototype.substring() の代わりに unicode-substring をオススメされたので、早速使ってみました。
substring, unicode-substring の Node.js repl 実行例
const unicodeSubstring = require('unicode-substring');
const string = "💥💥Emoji💥💥";
// str.substring(indexStart[, indexEnd])
console.log(string.substring(0, 3)); // 💥�
// unicodeSubstring(string, start, end)
console.log(unicodeSubstring(string, 0, 3)); // 💥💥E
substring vs unicode-substring サンプルコード
上記の pull request のコードにて http://localhost:3000/unicode からフォーム送信した結果が以下のとおりです。
GET /unicode
POST /unicode/substring
実行結果 – Response JSON
unicode-substring – npm
{
body: {
substring: "💥💥Emoji💥💥",
unicodeSubstring: "💥💥Emoji💥💥",
start: "0",
end: "3"
},
formatted: {
substring: "💥�",
unicodeSubstring: "💥💥E"
}
}
Code Reading) unicode-substring
unicode-substring/index.js はコード量が少ないので、もし時間があれば Code Reading してみると Unicode の理解が深まると思います。
以上、JavaScript や Node.js で Unicode を含む文字列には substring ではなく unicode-substring を使うべきという学びを得た、現場からお送りしました。