const anyString = "it will be available to watch until Sunday 11am PT / 2pm ET**";
console.log(`index:0, character: ${anyString.charAt(0)}`);
console.log(`index:1, character: ${anyString.charAt(1)}`);
console.log(`index:2, character: ${anyString.charAt(2)}`);
index:0, character: "i"
index:1, character: "t"
index:2, character: ""
let str = 'A\uD87E\uDC04Z';
for (var i = 0, chr; i < str.length; i++) {
console.log(str.charAt(i));
}
// expected output: "A"
// "๏ฟฝ"
// "๏ฟฝ"
// "Z"
console.log(str.charAt(1) + str.charAt(2)) // "ไฝ "
let str = 'A\uD87E\uDC04Z'; // ๋ํ ๋น BMP ๋ฌธ์๋ฅผ ์ง์ ์ฌ์ฉํ ์๋ ์๋ค.
for (let i = 0, chr; i < str.length; i++) {
[chr, i] = getWholeCharAndI(str, i);
// ์ ์ฒด ๋ฌธ์์ด๊ณผ ํ์ฌ current iterationd์ ์ ๋ฌํ๊ณ
// ๊ฐ๋ณ ๋ฌธ์์ i๊ฐ์ ๊ฐ์ง Array๋ฅผ ๋ฐํํ๋ค.(surrogate pair ์๋ ๊ฒฝ์ฐ์๋ง ๋ณ๊ฒฝ๋๋ค.)
console.log(chr);
}
function getWholeCharAndI(str, i) {
let code = str.charCodeAt(i);
if(Number.isNaN(code)) {
return ''; // ์์น๋ฅผ ์ฐพ์ ์ ์์
}
if(code < 0xD800 || code > 0xDFFF) {
return [str.charAt(i), i]; // Normal character, 'i'๋ ๊ทธ๋๋ก ์ ์ง
}
// High surrogate
// high private surrogates๋ฅผ ๋จ์ผ ๋ฌธ์๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํด ๋ง์ง๋ง 16์ง์๋ฅผ 0xDB7F๋ก ๋ณ๊ฒฝํ ์ ์์
if(0xD800 <= code && code <= 0xDBFF) {
// 16๋นํธ ์ฝ๋ ๋๊ฐ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฌธ์ ํ๋๋ฅผ ํํํ ๊ฒ์ surrogate pair๋ผ๊ณ ํ๋ฉฐ high surrogate, low surrogate๋ก ์ด๋ฃจ์ด์ง
// low surrogate๊ฐ ์๋ ๊ฒฝ์ฐ
if(str.length <= (i + 1)) {
throw 'High surrogate without following low surrogate';
}
let next = str.charCodeAt(i + 1);
if(0xDC00 > next || next > 0xDFFF) {
throw 'High surrogate without following low surrogate';
}
return [str.charAt(i) + str.charAt(i + 1), i + 1];
}
// Low surrogate (0xDC00 <= code && code <= 0xDFFF)
if(i === 0) {
throw 'Low surrogate without preceding high surrogate';
}
let prev = str.charCodeAt(i - 1);
// high private surrogates๋ฅผ ๋จ์ผ ๋ฌธ์๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํด ๋ง์ง๋ง 16์ง์๋ฅผ 0xDB7F๋ก ๋ณ๊ฒฝํ ์ ์์
if(0xD800 > prev || prev > 0xDBFF) {
throw 'Low surrogate without preceding high surrogate';
}
// ๋์ ๋ค์ ๋ฌธ์ ๋ฐํ(๋ฐ ์ฆ๊ฐ)
return [str.charAt(i + 1), i + 1];
}
let str = 'A\uD87E\uDC04Z';
console.log(fixedCharAt(str,1));
function fixedCharAt(str, idx) {
let ret = '';
str += '';
let end = str.length;
let surrogatePairs = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
while ((surrogatePairs.exec(str) != null)) {
let li = surrogatePairs.lastIndex;
if (li - 2 < idx) {
idx ++
} else {
break;
}
}
if(idx >= end || idx < 0) return '';
ret += str.charAt(idx);
if(/[\uD800-\uDBFF]/.test(ret) && /[\uDC00-\uDFFF]/.test(str.charAt(idx + 1))) {
ret += str.charAt(idx + 1);
}
return ret;
}