Note
ãã®ããŒãžã«ã¢ã¯ã»ã¹ããã«ã¯ãæ¿èªãå¿ èŠã§ãã ãµã€ã³ã€ã³ãŸãã¯ãã£ã¬ã¯ããªã®å€æŽã詊ãããšãã§ããŸãã
ãã®ããŒãžã«ã¢ã¯ã»ã¹ããã«ã¯ãæ¿èªãå¿ èŠã§ãã ãã£ã¬ã¯ããªã®å€æŽã詊ãããšãã§ããŸãã
ãã®èšäºã§ã¯ã.NET ã§äœ¿çšãããæåãšã³ã³ãŒã ã·ã¹ãã ã®æŠèŠã«ã€ããŠèª¬æããŸãã ãã®èšäºã§ã¯ãStringãCharãRuneãããã³ StringInfo åã UnicodeãUTF-16ãããã³ UTF-8 ã§ã©ã®ããã«åäœãããã«ã€ããŠèª¬æããŸãã
ããã§ã¯ã"æå" ãšããçšèªã "èªè ã 1 ã€ã®è¡šç€ºèŠçŽ ãšããŠèªèãããã®" ãšããå šè¬çãªæå³ã§äœ¿çšãããŸãã äžè¬çãªäŸãšããŠã¯ãæå "a"ãèšå· "@"ãçµµæå "ð" ãªã©ããããŸãã å Žåã«ãã£ãŠã¯ã1 ã€ã®æåã«èŠãããã®ããæžèšçŽ ã¯ã©ã¹ã¿ãŒã«é¢ããã»ã¯ã·ã§ã³ã§èª¬æããŠããããã«ãå®éã«ã¯è€æ°ã®ç¬ç«ãã衚瀺èŠçŽ ã§æ§æãããŠããããšããããŸãã
string åãš char å
string ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã¯ãäœããã®ããã¹ãã衚ããŸãã
string ã¯ãè«ççã«ã¯ 16 ãããå€ã®ã·ãŒã±ã³ã¹ã§ããããã®ããããã char æ§é äœã®ã€ã³ã¹ã¿ã³ã¹ã§ãã
string.Length ããããã£ã§ã¯ãchar ã€ã³ã¹ã¿ã³ã¹ã«å«ãŸãã string ã€ã³ã¹ã¿ã³ã¹ã®æ°ãè¿ãããŸãã
次ã®ãµã³ãã«é¢æ°ã§ã¯ãchar ã«å«ãŸãããã¹ãŠã® string ã€ã³ã¹ã¿ã³ã¹ã® 16 é²è¡šèšã®å€ãåºåãããŸãã
void PrintChars(string s)
{
Console.WriteLine($"\"{s}\".Length = {s.Length}");
for (int i = 0; i < s.Length; i++)
{
Console.WriteLine($"s[{i}] = '{s[i]}' ('\\u{(int)s[i]:x4}')");
}
Console.WriteLine();
}
ãã®é¢æ°ã« string "Hello" ãæž¡ããšã次ã®åºåãåŸãããŸãã
PrintChars("Hello");
"Hello".Length = 5
s[0] = 'H' ('\u0048')
s[1] = 'e' ('\u0065')
s[2] = 'l' ('\u006c')
s[3] = 'l' ('\u006c')
s[4] = 'o' ('\u006f')
åæåã¯ã1 ã€ã® char å€ã§è¡šãããŸãã ãã®ãã¿ãŒã³ã¯ãäžçã®ã»ãšãã©ã®èšèªã«åœãŠã¯ãŸããŸãã ããšãã°ãnÇ hÇo ã®ããã«çºé³ã "ããã«ã¡ã¯" ãæå³ããäžåœèªã® 2 æåã«å¯Ÿããåºåãæ¬¡ã«ç€ºããŸãã
PrintChars("äœ å¥œ");
"äœ å¥œ".Length = 2
s[0] = 'äœ ' ('\u4f60')
s[1] = '奜' ('\u597d')
ãã ããäžéšã®èšèªããã³äžéšã®èšå·ãšçµµæåã«ã€ããŠã¯ã1 ã€ã®æåã衚ãããã« 2 ã€ã® char ã€ã³ã¹ã¿ã³ã¹ãå¿
èŠã§ãã ããšãã°ããªã»ãŒãžèªã§ããªã»ãŒãžããæå³ããåèªã«å«ãŸããæåãš char ã®äŸãæ¯èŒããŠãã ããã
PrintChars("ððð»ðð»ð ð»ð");
"ððð»ðð»ð ð»ð".Length = 17
s[0] = 'ᅵ' ('\ud801')
s[1] = 'ᅵ' ('\udccf')
s[2] = 'ᅵ' ('\ud801')
s[3] = 'ᅵ' ('\udcd8')
s[4] = 'ᅵ' ('\ud801')
s[5] = 'ᅵ' ('\udcfb')
s[6] = 'ᅵ' ('\ud801')
s[7] = 'ᅵ' ('\udcd8')
s[8] = 'ᅵ' ('\ud801')
s[9] = 'ᅵ' ('\udcfb')
s[10] = 'ᅵ' ('\ud801')
s[11] = 'ᅵ' ('\udcdf')
s[12] = ' ' ('\u0020')
s[13] = 'ᅵ' ('\ud801')
s[14] = 'ᅵ' ('\udcbb')
s[15] = 'ᅵ' ('\ud801')
s[16] = 'ᅵ' ('\udcdf')
åã®äŸã§ã¯ã空çœãé€ãåæåã 2 ã€ã® char ã€ã³ã¹ã¿ã³ã¹ã«ãã£ãŠè¡šãããŠããŸãã
ãŸããéçã®çµµæåãè¡šãæ¬¡ã®äŸã§ç€ºãããã«ã1 ã€ã® Unicode çµµæåã 2 ã€ã® char ã«ãã£ãŠè¡šãããŸãã
"ð".Length = 2
s[0] = 'ᅵ' ('\ud83d')
s[1] = 'ᅵ' ('\udc02')
ãããã®äŸã§ã¯ãstring.Length ã€ã³ã¹ã¿ã³ã¹ã®æ°ã瀺ã char ã®å€ããå¿
ããã衚瀺ãããæåæ°ã瀺ããŠããªãããšãããããŸãã 1 ã€ã® char ã€ã³ã¹ã¿ã³ã¹ã¯ãå¿
ãããããèªäœã§ 1 æåã衚ããšã¯éããŸããã
1 ã€ã®æåã«ãããããã char ã®ãã¢ã¯ã"ãµãã²ãŒã ãã¢" ãšåŒã°ããŸãã ããããã©ã®ããã«åäœããããçè§£ããã«ã¯ãUnicode ãš UTF-16 ã®ãšã³ã³ãŒãã«ã€ããŠçè§£ããå¿
èŠããããŸãã
Unicode ã³ãŒã ãã€ã³ã
Unicode ã¯ãããŸããŸãªãã©ãããã©ãŒã äžã§ãããŸããŸãªèšèªãšã¹ã¯ãªããã§äœ¿çšããããã®åœéãšã³ã³ãŒãæšæºã§ãã
Unicode æšæºã§ã¯ã110 äžåãè¶
ããã³ãŒã ãã€ã³ããå®çŸ©ãããŠããŸãã ã³ãŒã ãã€ã³ãã¯ã0 ãã U+10FFFF (10 鲿°ã® 1,114,111) ãŸã§ã®ç¯å²ã®æŽæ°å€ã§ãã äžéšã®ã³ãŒã ãã€ã³ãã¯ãæåãèšå·ããŸãã¯çµµæåã«å²ãåœãŠãããŠããŸãã ãã®ä»ã¯ãæ°ããè¡ã«é²ããªã©ãããã¹ããæåã®è¡šç€ºæ¹æ³ãå¶åŸ¡ããã¢ã¯ã·ã§ã³ã«å²ãåœãŠãããŠããŸãã å€ãã®ã³ãŒã ãã€ã³ãã¯ãŸã å²ãåœãŠãããŠããŸããã
ã³ãŒã ãã€ã³ãã®å²ãåœãŠã®ããã€ãã®äŸãšãããããèšèŒãããŠãã Unicode 衚ãžã®ãªã³ã¯ã次ã«ç€ºããŸãã
| 10鲿³ | ããã¯ã¹ | äŸ | 説æ |
|---|---|---|---|
| 10 | U+000A |
ãªã | ã©ã€ã³ãã£ãŒã |
| 97 | U+0061 |
am | ã©ãã³å°æå A |
| 562 | U+0232 |
Ȳ | ãã¯ãã³ä»ãã©ãã³å€§æå Y |
| 68,675 | U+10C43 |
ð± | å€ãã¥ã«ã¯èªæåãªã«ãã³ AT |
| 127,801 | U+1F339 |
ð¹ | ãã©ã®çµµæå |
ã³ãŒã ãã€ã³ãã¯ãç¿æ
£çã«ãU+xxxx æ§æã䜿çšããŠåç
§ãããŸããxxxx 㯠16 é²ãšã³ã³ãŒãã®æŽæ°å€ã§ãã
ã³ãŒã ãã€ã³ãã®å šç¯å²å ã«ã¯ã次㮠2 ã€ã®éšåç¯å²ããããŸãã
-
åºæ¬å€èšèªé¢ (BMP) ã®ç¯å²
U+0000..U+FFFFã ãã® 16 ãããã®ç¯å²ã«ãã£ãŠ 65,536 åã®ã³ãŒã ãã€ã³ããæäŸãããäžçã®æžèšäœç³»ã®å€§éšåãååã«ã«ããŒã§ããŸãã -
è£å©ã³ãŒããã€ã³ã ã®ç¯å²
U+10000..U+10FFFFã ãã® 21 ãããã®ç¯å²ã«ãã£ãŠã100 äžåãè¶ ãã远å ã®ã³ãŒã ãã€ã³ããæäŸãããŸããããã¯ãããŸãäžè¬çã§ã¯ãªãèšèªããçµµæåãªã©ã®ãã®ä»ã®ç®çã®ããã«äœ¿çšã§ããŸãã
次ã®å³ã¯ãBMP ãšè£å©ã³ãŒã ãã€ã³ãã®é¢ä¿ã瀺ããŠããŸãã
UTF-16 ã³ãŒãåäœ
16 ããã Unicode Transformation Format (UTF-16) ã¯ã16 ãããã® "ã³ãŒãåäœ" ã䜿çšã㊠Unicode ã³ãŒã ãã€ã³ãã衚ããæåãšã³ã³ãŒã ã·ã¹ãã ã§ãã .NET ã§ã¯ãstring å
ã®ããã¹ãããšã³ã³ãŒãããããã« UTF-16 ã䜿çšãããŠããŸãã
char ã€ã³ã¹ã¿ã³ã¹ã¯ã16 ãããã®ã³ãŒãåäœã衚ããŸãã
1 ã€ã® 16 ããã ã³ãŒãåäœã¯ãåºæ¬å€èšèªé¢ã® 16 ãããç¯å²ã«å«ãŸããä»»æã®ã³ãŒã ãã€ã³ãã衚ãããšãã§ããŸãã ãã ããè£å©ç¯å²å
ã®ã³ãŒã ãã€ã³ãã«ã€ããŠã¯ã2 ã€ã® char ã€ã³ã¹ã¿ã³ã¹ãå¿
èŠã§ãã
ãµãã²ãŒã ãã¢
2 ã€ã® 16 ãããå€ãã 1 ã€ã® 21 ãããå€ãžã®å€æã¯ã代çšç¬Šå·äœçœ®ãšåŒã°ããç¹æ®ãªç¯å²ã䜿çšããŠè¡ãããŸãããã®ç¯å²ã¯ U+D800 ãã U+DFFF (10 鲿°ã® 55,296 ãã 57,343) ãå«ã¿ãŸãã
次ã®å³ã¯ãBMP ãšãµãã²ãŒã ã³ãŒã ãã€ã³ãã®é¢ä¿ã瀺ããŠããŸãã
"äžäœãµãã²ãŒã" ã³ãŒã ãã€ã³ã (U+D800..U+DBFF) ã®çŽåŸã« "äžäœãµãã²ãŒã" ã³ãŒã ãã€ã³ã (U+DC00..U+DFFF) ãç¶ãå Žåããã®ãã¢ã¯ãæ¬¡ã®æ°åŒã䜿çšããŠè£å©ã³ãŒã ãã€ã³ããšããŠè§£éãããŸãã
code point = 0x10000 +
((high surrogate code point - 0xD800) * 0x0400) +
(low surrogate code point - 0xDC00)
10 é²è¡šèšã䜿çšããåãæ°åŒã次ã«ç€ºããŸãã
code point = 65,536 +
((high surrogate code point - 55,296) * 1,024) +
(low surrogate code point - 56,320)
"äžäœ" ãµãã²ãŒã ã³ãŒã ãã€ã³ãã«ã¯ã"äžäœ" ãµãã²ãŒã ã³ãŒã ãã€ã³ãããã倧ããæ°å€ã¯å«ãŸããŸããã äžäœãµãã²ãŒã ã³ãŒã ãã€ã³ãã "äžäœ" ãšåŒã°ããçç±ã¯ã20 ãããã®ã³ãŒã ãã€ã³ãç¯å²ã®äžäœ 10 ããããèšç®ããããã«äœ¿çšãããããã§ãã äžäœãµãã²ãŒã ã³ãŒã ãã€ã³ãã¯ãäžäœ 10 ããããèšç®ããããã«äœ¿çšãããŸãã
ããšãã°ã0xD83C ãš 0xDF39 ã®ãµãã²ãŒã ãã¢ã«å¯Ÿå¿ããå®éã®ã³ãŒã ãã€ã³ãã¯ã次ã®ããã«èšç®ãããŸãã
actual = 0x10000 + ((0xD83C - 0xD800) * 0x0400) + (0xDF39 - 0xDC00)
= 0x10000 + ( 0x003C * 0x0400) + 0x0339
= 0x10000 + 0xF000 + 0x0339
= 0x1F339
10 é²è¡šèšã䜿çšããåãèšç®ã次ã«ç€ºããŸãã
actual = 65,536 + ((55,356 - 55,296) * 1,024) + (57,145 - 56320)
= 65,536 + ( 60 * 1,024) + 825
= 65,536 + 61,440 + 825
= 127,801
åã®äŸã§ã¯ã"\ud83c\udf39" ããåè¿°ã® U+1F339 ROSE ('ð¹') ã³ãŒã ãã€ã³ãã® UTF-16 ãšã³ã³ãŒãã§ããããšã瀺ãããŠããŸãã
Unicode ã¹ã«ã©ãŒå€
Unicode ã¹ã«ã©ãŒå€ãšããçšèªã¯ããµãã²ãŒã ã³ãŒã ãã€ã³ã以å€ã®ãã¹ãŠã®ã³ãŒã ãã€ã³ããæããŸãã ã€ãŸããã¹ã«ã©ãŒå€ãšã¯ãæåãå²ãåœãŠãããŠããããå°æ¥æåãå²ãåœãŠãããå¯èœæ§ãããã³ãŒã ãã€ã³ãã§ãã ããã§ã® "æå" ã¯ãã³ãŒã ãã€ã³ãã«å²ãåœãŠãããšãã§ãããã¹ãŠã®ãã®ãæããŸããããã«ã¯ãããã¹ããæåã®è¡šç€ºæ¹æ³ãå¶åŸ¡ããã¢ã¯ã·ã§ã³ãªã©ãå«ãŸããŸãã
次ã®å³ã¯ãã¹ã«ã©ãŒå€ã®ã³ãŒã ãã€ã³ãã瀺ããŠããŸãã
ã¹ã«ã©ãŒå€ãšããŠã® Rune å
éèŠ
.NET Framework ã§ã¯ Rune åã䜿çšã§ããŸããã
.NET ã§ãSystem.Text.Rune å㯠Unicode ã¹ã«ã©ãŒå€ã衚ããŸãã
Rune ã³ã³ã¹ãã©ã¯ã¿ãŒã§ã¯ãçæãããã€ã³ã¹ã¿ã³ã¹ãæå¹ãª Unicode ã¹ã«ã©ãŒå€ã§ããããšãæ€èšŒãããŸããããã§ãªãå Žåã¯ãäŸå€ãã¹ããŒãããŸãã æ¬¡ã®äŸã¯ãRune ã€ã³ã¹ã¿ã³ã¹ã®ã€ã³ã¹ã¿ã³ã¹åã«æåããã³ãŒãã瀺ããŠããŸããå
¥åãæå¹ãªã¹ã«ã©ãŒå€ã衚ããŠããããã§ãã
Rune a = new Rune('a');
Rune b = new Rune(0x0061);
Rune c = new Rune('\u0061');
Rune d = new Rune(0x10421);
Rune e = new Rune('\ud801', '\udc21');
次ã®äŸã§ã¯ãã³ãŒã ãã€ã³ãããµãã²ãŒãç¯å²å ã§ãããªãããµãã²ãŒã ãã¢ãæ§æããŠããªããããäŸå€ãã¹ããŒãããŸãã
Rune f = new Rune('\ud801');
次ã®äŸã§ã¯ãã³ãŒã ãã€ã³ããè£å©ç¯å²ãè¶ ããŠãããããäŸå€ãã¹ããŒãããŸãã
Rune g = new Rune(0x12345678);
Rune ã®äœ¿çšäŸ: 倧æåãšå°æåã®å€æŽ
char ãåãåããã¹ã«ã©ãŒå€ã§ããã³ãŒã ãã€ã³ããæäœããŠãããšä»®å®ãã API ã¯ããã® char ããµãã²ãŒã ãã¢ã®ãã®ã§ãã£ãå Žåãæ£ããåäœããŸããã ããšãã°ãChar.ToUpperInvariant ã«å«ãŸããå char ã«å¯Ÿã㊠string ãåŒã³åºããæ¬¡ã®ãããªã¡ãœãããèããŠã¿ãŸãã
// THE FOLLOWING METHOD SHOWS INCORRECT CODE.
// DO NOT DO THIS IN A PRODUCTION APPLICATION.
static string ConvertToUpperBadExample(string input)
{
StringBuilder builder = new StringBuilder(input.Length);
for (int i = 0; i < input.Length; i++) /* or 'foreach' */
{
builder.Append(char.ToUpperInvariant(input[i]));
}
return builder.ToString();
}
input
string ã«å°æåã®ãã¶ã¬ããæå er (ð) ãå«ãŸããŠããå Žåã¯ããã®ã³ãŒãã䜿çšããŠãã倧æå (ð¡) ã«å€æããããšãã§ããŸããã ãã®ã³ãŒãã§ã¯ãchar.ToUpperInvariant ãš U+D801 ã®åãµãã²ãŒã ã³ãŒã ãã€ã³ãã«å¯ŸããŠãåå¥ã« U+DC49 ãåŒã³åºãããŸãã ããããU+D801 èªäœã«ã¯ããããå°æåãšããŠèå¥ããã®ã«ååãªæ
å ±ãå«ãŸããŠããªããããchar.ToUpperInvariant ã«ãã倿Žã¯è¡ãããŸããã ãŸããU+DC49 ãåãæ¹æ³ã§åŠçãããŸãã ãã®çµæã inputstring ã®å°æå 'á§©' ã¯å€§æåã® 'á§' ã«å€æãããŸããã
string ãé©åã«å€§æåã«å€æããããã® 2 ã€ã®ãªãã·ã§ã³ã次ã«ç€ºããŸãã
String.ToUpperInvariant ãã string ãžãšå埩åŠçããã®ã§ã¯ãªããå ¥å
charã«å¯ŸããŠcharãåŒã³åºããŸããstring.ToUpperInvariantã¡ãœããã¯åãµãã²ãŒã ãã¢ã®äž¡æ¹ã®éšåã«ã¢ã¯ã»ã¹ã§ããããããã¹ãŠã® Unicode ã³ãŒã ãã€ã³ããæ£ããåŠçã§ããŸããæ¬¡ã®äŸã«ç€ºãããã«ã
Runeã€ã³ã¹ã¿ã³ã¹ã§ã¯ãªãcharã€ã³ã¹ã¿ã³ã¹ãšã㊠Unicode ã¹ã«ã©ãŒå€ãå埩åŠçããŸããRuneã€ã³ã¹ã¿ã³ã¹ã¯æå¹ãª Unicode ã¹ã«ã©ãŒå€ã§ãããããã¹ã«ã©ãŒå€ã«å¯ŸããŠåäœããããšãæ³å®ãããŠãã API ã«æž¡ãããšãã§ããŸãã ããšãã°ã次ã®äŸã«ç€ºãããã« Rune.ToUpperInvariant ãåŒã³åºããšãæ£ããçµæãåŸãããŸããstatic string ConvertToUpper(string input) { StringBuilder builder = new StringBuilder(input.Length); foreach (Rune rune in input.EnumerateRunes()) { builder.Append(Rune.ToUpperInvariant(rune)); } return builder.ToString(); }
ãã®ä»ã® Rune API
Rune åã§ã¯ãå€ãã® char API ãšé¡äŒŒããæ©èœãå
¬éãããŠããŸãã ããšãã°ã以äžã®ã¡ãœããã¯ãchar åã®éç API ã«å¯Ÿå¿ããŠããŸãã
Rune ã€ã³ã¹ã¿ã³ã¹ããçã®ã¹ã«ã©ãŒå€ãååŸããã«ã¯ãRune.Value ããããã£ã䜿çšããŸãã
Rune ã€ã³ã¹ã¿ã³ã¹ãåã³ char ã®ã·ãŒã±ã³ã¹ã«å€æããã«ã¯ãRune.ToString ãŸã㯠Rune.EncodeToUtf16 ã¡ãœããã䜿çšããŸãã
ãã¹ãŠã® Unicode ã¹ã«ã©ãŒå€ã¯ 1 ã€ã® char ãŸãã¯ãµãã²ãŒã ãã¢ã«ãã£ãŠè¡šãããšãã§ããããããããã Rune ã€ã³ã¹ã¿ã³ã¹ã¯å€ããŠã 2 ã€ã® char ã€ã³ã¹ã¿ã³ã¹ã«ãã£ãŠè¡šãããšãã§ããŸãã
Rune.Utf16SequenceLength ã€ã³ã¹ã¿ã³ã¹ã衚ãããã«å¿
èŠãª char ã€ã³ã¹ã¿ã³ã¹ã®æ°ã確èªããã«ã¯ãRune ã䜿çšããŸãã
.NET ã® Rune åã®è©³çްã«ã€ããŠã¯ãRune API ãªãã¡ã¬ã³ã¹ãåç
§ããŠãã ããã
æžèšçŽ ã¯ã©ã¹ã¿ãŒ
1 ã€ã®æåã«èŠãããã®ããè€æ°ã®ã³ãŒã ãã€ã³ãã®çµã¿åããããçæãããŠããå ŽåããããŸãããã®ããã"æå" ã®ä»£ããã«äœ¿çšãããããšãå€ããæžèšçŽ ã¯ã©ã¹ã¿ãŒãšããããããããããçšèªããããŸãã .NET ã«ãããåçã®çšèªã¯ãããã¹ãèŠçŽ ã§ãã
string ã€ã³ã¹ã¿ã³ã¹ "a"ã"á"ã"aÌ"ã"ð©ðœâð" ã«ã€ããŠèããŠã¿ãŸãããã ã䜿ãã®ãªãã¬ãŒãã£ã³ã° ã·ã¹ãã ã«ãã£ãŠãããã Unicode æšæºã§æå®ãããŠãããšããã«åŠçãããå Žåããããã®å string ã€ã³ã¹ã¿ã³ã¹ã¯ã1 ã€ã®ããã¹ãèŠçŽ ããŸãã¯æžèšçŽ ã¯ã©ã¹ã¿ãŒãšããŠè¡šç€ºãããŸãã ãã ããæåŸã® 2 ã€ã¯ãè€æ°ã®ã¹ã«ã©ãŒå€ã³ãŒã ãã€ã³ãã«ãã£ãŠè¡šãããŸãã
string "a" 㯠1 ã€ã®ã¹ã«ã©ãŒå€ã§è¡šããã1 ã€ã®
charã€ã³ã¹ã¿ã³ã¹ãå«ãŸããŸããU+0061 LATIN SMALL LETTER A
string "aÌ" 㯠1 ã€ã®ã¹ã«ã©ãŒå€ã§è¡šããã1 ã€ã®
charã€ã³ã¹ã¿ã³ã¹ãå«ãŸããŸããU+00E1 LATIN SMALL LETTER A WITH ACUTE
string "aÌ" ã¯ã"aÌ" ãšåãããã«èŠããŸããã2 ã€ã®ã¹ã«ã©ãŒå€ã§è¡šããã2 ã€ã®
charã€ã³ã¹ã¿ã³ã¹ãå«ãŸããŸããU+0061 LATIN SMALL LETTER AU+0301 COMBINING ACUTE ACCENT
æåŸã«ãstring "
ð©ðœâð" 㯠4 ã€ã®ã¹ã«ã©ãŒå€ã§è¡šããã7 ã€ã®charã€ã³ã¹ã¿ã³ã¹ãå«ãŸããŸãã-
U+1F469 WOMAN(è£å©ç¯å²ããµãã²ãŒã ãã¢ãå¿ èŠ) -
U+1F3FD EMOJI MODIFIER FITZPATRICK TYPE-4(è£å©ç¯å²ããµãã²ãŒã ãã¢ãå¿ èŠ) U+200D ZERO WIDTH JOINER-
U+1F692 FIRE ENGINE(è£å©ç¯å²ããµãã²ãŒã ãã¢ãå¿ èŠ)
-
åã®äŸã®äžéš (çµåã¢ã¯ã»ã³ãã®ä¿®é£Ÿåãèã®è²ã®ä¿®é£Ÿåãªã©) ã§ã¯ãã³ãŒã ãã€ã³ããç»é¢ã«ã¹ã¿ã³ãã¢ãã³èŠçŽ ãšããŠè¡šç€ºãããŸããã 代ããã«ãããã¯ããã®åã«çŸããããã¹ãèŠçŽ ã®å€èгã倿Žãã圹å²ãæãããŠããŸãã ãããã®äŸã¯ã1 ã€ã® "æå" ãŸã㯠"æžèšçŽ ã¯ã©ã¹ã¿ãŒ" ãšèŠãªããããã®ãæ§æããããã«ãè€æ°ã®ã¹ã«ã©ãŒå€ãå¿ èŠã«ãªãå Žåãããããšã瀺ããŠããŸãã
string ã®æžèšçŽ ã¯ã©ã¹ã¿ãŒãåæããã«ã¯ã次ã®äŸã«ç€ºãããã« StringInfo ã¯ã©ã¹ã䜿çšããŸãã Swift ã«æ
£ããŠããå Žåã.NET ã® StringInfo åã¯ãæŠå¿µçã« Swift ã® character åãšäŒŒãŠããŸãã
äŸ: charãRuneãããã¹ãèŠçŽ ã®ã€ã³ã¹ã¿ã³ã¹æ°ãæ°ãã
.NET API ã§ã¯ãæžèšçŽ ã¯ã©ã¹ã¿ãŒã¯ "ããã¹ãèŠçŽ " ãšåŒã°ããŸãã æ¬¡ã®ã¡ãœããã¯ãchar ã«å«ãŸãã Runeãstringãããã³ããã¹ãèŠçŽ ã®ã€ã³ã¹ã¿ã³ã¹ã®éãã瀺ããŠããŸãã
static void PrintTextElementCount(string s)
{
Console.WriteLine(s);
Console.WriteLine($"Number of chars: {s.Length}");
Console.WriteLine($"Number of runes: {s.EnumerateRunes().Count()}");
TextElementEnumerator enumerator = StringInfo.GetTextElementEnumerator(s);
int textElementCount = 0;
while (enumerator.MoveNext())
{
textElementCount++;
}
Console.WriteLine($"Number of text elements: {textElementCount}");
}
PrintTextElementCount("a");
// Number of chars: 1
// Number of runes: 1
// Number of text elements: 1
PrintTextElementCount("aÌ");
// Number of chars: 2
// Number of runes: 2
// Number of text elements: 1
PrintTextElementCount("ð©ðœâð");
// Number of chars: 7
// Number of runes: 4
// Number of text elements: 1
äŸ: string ã€ã³ã¹ã¿ã³ã¹ã®åå²
string ã€ã³ã¹ã¿ã³ã¹ãåå²ããå Žåã¯ããµãã²ãŒã ãã¢ãšæžèšçŽ ã¯ã©ã¹ã¿ãŒãåå²ããªãããã«ããŸãã äžé©åãªã³ãŒããç€ºãæ¬¡ã®äŸã«ã€ããŠèããŠã¿ãŸããããããã§ã¯ãstring å
ã® 10 æåããšã«æ¹è¡ãæ¿å
¥ããããšããŠããŸãã
// THE FOLLOWING METHOD SHOWS INCORRECT CODE.
// DO NOT DO THIS IN A PRODUCTION APPLICATION.
static string InsertNewlinesEveryTencharsBadExample(string input)
{
StringBuilder builder = new StringBuilder();
// First, append chunks in multiples of 10 chars
// followed by a newline.
int i = 0;
for (; i < input.Length - 10; i += 10)
{
builder.Append(input, i, 10);
builder.AppendLine(); // newline
}
// Then append any leftover data followed by
// a final newline.
builder.Append(input, i, input.Length - i);
builder.AppendLine(); // newline
return builder.ToString();
}
ãã®ã³ãŒãã§ã¯ char ã€ã³ã¹ã¿ã³ã¹ãåæãããŠããããã10-char ã®å¢çã«ãŸããããµãã²ãŒã ãã¢ã¯åå²ããããããã®éã«æ¹è¡ãæ¿å
¥ãããŸãã ãµãã²ãŒã ã³ãŒã ãã€ã³ãã¯ãã¢ãšããŠã®ã¿æå³ãããã®ã§ããã®æ¿å
¥ã«ãã£ãŠããŒã¿ã®ç ŽæãçºçããŸãã
ããŒã¿ã®ç Žæã®å¯èœæ§ã¯ãRune ã€ã³ã¹ã¿ã³ã¹ã§ã¯ãªã char ã€ã³ã¹ã¿ã³ã¹ (ã¹ã«ã©ãŒå€) ãåæããŠããªããªããŸããã
Rune ã€ã³ã¹ã¿ã³ã¹ã®ã»ããã10-char ã®å¢çã«ãŸãããæžèšçŽ ã¯ã©ã¹ã¿ãŒãæ§æããå¯èœæ§ããããŸãã æžèšçŽ ã¯ã©ã¹ã¿ãŒã®ã»ãããåå²ãããå Žåã¯ãæ£ããè§£éã§ããŸããã
ããé©åãªã¢ãããŒãã¯ã次ã®äŸã®ããã«ãæžèšçŽ ã¯ã©ã¹ã¿ãŒ (ãŸãã¯ããã¹ãèŠçŽ ) ãã«ãŠã³ãããããšã«ãã£ãŠ string ãåå²ããããšã§ãã
static string InsertNewlinesEveryTenTextElements(string input)
{
StringBuilder builder = new StringBuilder();
// Append chunks in multiples of 10 chars
TextElementEnumerator enumerator = StringInfo.GetTextElementEnumerator(input);
int textElementCount = 1;
while (enumerator.MoveNext())
{
builder.Append(enumerator.Current);
if (textElementCount % 10 == 0)
{
builder.AppendLine(); // newline
}
textElementCount++;
}
// Add a final newline.
builder.AppendLine(); // newline
return builder.ToString();
}
äžèšã®ããã«ã.NET 5 以åã§ã¯ãStringInfo ã¯ã©ã¹ã«ã¯ãäžéšã®æžèšçŽ ã¯ã©ã¹ã¿ãŒãæ£ããåŠçãããªããšãããã°ããããŸããã
UTF-8 ãš UTF-32
åã®ã»ã¯ã·ã§ã³ã§ã¯ãUTF-16 ã«çŠç¹ãåœãŠãŸããã .NET ã§ã¯ string ã€ã³ã¹ã¿ã³ã¹ããšã³ã³ãŒãããããã« UTF-16 ã䜿çšãããããã§ãã Unicode ã«ã¯ãä»ã®ãšã³ã³ãŒã ã·ã¹ãã ããããŸã: UTF-8 ãš UTF-32 ã§ãã ãããã®ãšã³ã³ãŒãã§ã¯ã8 ãããã®ã³ãŒãåäœãš 32 ãããã®ã³ãŒãåäœããããã䜿çšãããŸãã
UTF-16 ãšåæ§ã«ãUTF-8 ã§ã¯ãäžéšã® Unicode ã¹ã«ã©ãŒå€ã衚ãããã«è€æ°ã®ã³ãŒãåäœãå¿ èŠã«ãªããŸãã UTF-32 ã§ã¯ã1 ã€ã® 32 ããã ã³ãŒãåäœã§ä»»æã®ã¹ã«ã©ãŒå€ã衚ãããšãã§ããŸãã
ããã 3 ã€ã®å Unicode ãšã³ã³ãŒã ã·ã¹ãã ã§ãåã Unicode ã³ãŒã ãã€ã³ããã©ã®ããã«è¡šããããã瀺ãããã€ãã®äŸã次ã«ç€ºããŸãã
Scalar: U+0061 LATIN SMALL LETTER A ('a')
UTF-8 : [ 61 ] (1x 8-bit code unit = 8 bits total)
UTF-16: [ 0061 ] (1x 16-bit code unit = 16 bits total)
UTF-32: [ 00000061 ] (1x 32-bit code unit = 32 bits total)
Scalar: U+0429 CYRILLIC CAPITAL LETTER SHCHA ('Щ')
UTF-8 : [ D0 A9 ] (2x 8-bit code units = 16 bits total)
UTF-16: [ 0429 ] (1x 16-bit code unit = 16 bits total)
UTF-32: [ 00000429 ] (1x 32-bit code unit = 32 bits total)
Scalar: U+A992 JAVANESE LETTER GA ('êŠ')
UTF-8 : [ EA A6 92 ] (3x 8-bit code units = 24 bits total)
UTF-16: [ A992 ] (1x 16-bit code unit = 16 bits total)
UTF-32: [ 0000A992 ] (1x 32-bit code unit = 32 bits total)
Scalar: U+104CC OSAGE CAPITAL LETTER TSHA ('ð')
UTF-8 : [ F0 90 93 8C ] (4x 8-bit code units = 32 bits total)
UTF-16: [ D801 DCCC ] (2x 16-bit code units = 32 bits total)
UTF-32: [ 000104CC ] (1x 32-bit code unit = 32 bits total)
åè¿°ã®ããã«ããµãã²ãŒã ãã¢ã«ç±æ¥ãã 1 ã€ã® UTF-16 ã³ãŒãåäœã¯ãåç¬ã§ã¯æå³ããããŸããã åæ§ã«ã1 ã€ã® UTF-8 ã³ãŒãåäœããã¹ã«ã©ãŒå€ã®èšç®ã«äœ¿çšããã 2 ã€ã3 ã€ããŸã㯠4 ã€ã®ã·ãŒã±ã³ã¹ã«å«ãŸããŠããå Žåãããã¯åç¬ã§ã¯æå³ããããŸããã
泚æ
C# 11 以éã§ã¯ããªãã©ã« string ã« "u8" ãµãã£ãã¯ã¹ã䜿çšã㊠UTF-8 string ãªãã©ã«ã衚ãããšãã§ããŸãã UTF-8 string ãªãã©ã«ã®è©³çްã«ã€ããŠã¯ãC# ã¬ã€ãã®çµã¿èŸŒã¿åç §åã«é¢ããèšäºã®ããªãã©ã«ãã»ã¯ã·ã§ã³ãåç §ããŠãã ããã
ãšã³ãã£ã¢ã³
.NET ã§ã¯ãstring ã® UTF-16 ã³ãŒãåäœã¯ã16 ãããæŽæ° (char ã€ã³ã¹ã¿ã³ã¹) ã®ã·ãŒã±ã³ã¹ãšããŠé£ç¶ããã¡ã¢ãªã«æ ŒçŽãããŸãã åã
ã®ã³ãŒãåäœã®ãããã¯ãçŸåšã®ã¢ãŒããã¯ãã£ã®ãšã³ãã£ã¢ã³ã«åŸã£ãŠäžŠã¹ãããŸãã
ãªãã« ãšã³ãã£ã¢ã³ã®ã¢ãŒããã¯ãã£ã§ã¯ãUTF-16 ã³ãŒã ãã€ã³ã string ã§æ§æããã [ D801 DCCC ] ã¯ããã€ã [ 0x01, 0xD8, 0xCC, 0xDC ] ãšããŠã¡ã¢ãªå
ã«äžŠã¹ãããŸãã ããã° ãšã³ãã£ã¢ã³ã®ã¢ãŒããã¯ãã£ã§ã¯ãåã string ããã€ã [ 0xD8, 0x01, 0xDC, 0xCC ] ãšããŠã¡ã¢ãªå
ã«äžŠã¹ãããŸãã
çžäºã«éä¿¡ããã³ã³ãã¥ãŒã¿ãŒ ã·ã¹ãã ã¯ããããã¯ãŒã¯ãééããããŒã¿ã®è¡šçŸæ¹æ³ãäžèŽãããå¿
èŠããããŸãã ã»ãšãã©ã®ãããã¯ãŒã¯ ãããã³ã«ã§ã¯ãããã¹ãã®éä¿¡æã« UTF-8 ãæšæºãšããŠäœ¿çšãããŸãããã®çç±ã®äžéšã¯ãããã° ãšã³ãã£ã¢ã³ã®ã³ã³ãã¥ãŒã¿ãŒããªãã« ãšã³ãã£ã¢ã³ã®ã³ã³ãã¥ãŒã¿ãŒãšéä¿¡ããéã«çºçããå¯èœæ§ã®ããåé¡ãåé¿ããããã§ãã UTF-8 ã³ãŒã ãã€ã³ã string ã§æ§æããã [ F0 90 93 8C ] ã¯ããšã³ãã£ã¢ã³ã«é¢ä¿ãªãåžžã«ãã€ã [ 0xF0, 0x90, 0x93, 0x8C ] ãšããŠè¡šãããŸãã
UTF-8 ã䜿çšããŠããã¹ããéä¿¡ããå Žåã.NET ã¢ããªã±ãŒã·ã§ã³ã§ã¯ã次ã®äŸã®ãããªã³ãŒãã䜿çšãããããšããããããŸãã
string stringToWrite = GetString();
byte[] stringAsUtf8Bytes = Encoding.UTF8.GetBytes(stringToWrite);
await outputStream.WriteAsync(stringAsUtf8Bytes, 0, stringAsUtf8Bytes.Length);
åã®äŸã§ã¯ãã¡ãœãã Encoding.UTF8.GetBytes ã«ãã£ãŠ UTF-16 ã® string ãäžé£ã® Unicode ã¹ã«ã©ãŒå€ã«ãã³ãŒãããããã®ã¹ã«ã©ãŒå€ã UTF-8 ã«åãšã³ã³ãŒããããŠãçæãããã·ãŒã±ã³ã¹ã byte ã®é
åã«é
眮ãããŸãã ã¡ãœãã Encoding.UTF8.GetString ã§ã¯å察ã®å€æãå®è¡ãããŸããã€ãŸããUTF-8 ã® byte é
åã UTF-16 ã® string ã«å€æãããŸãã
èŠå
ã€ã³ã¿ãŒãããäžã§ã¯ UTF-8 ãäžè¬çã§ããããããããã¯ãŒã¯ããçãã€ããèªã¿åãããã®ããŒã¿ã UTF-8 ã§ãããã®ããã«æ±ããããªãå ŽåããããŸãã ãããããããæ¬åœã«é©åãªåœ¢åŒã§ããããšãæ€èšŒããå¿
èŠããããŸãã æªæã®ããã¯ã©ã€ã¢ã³ãããããªãã®ãµãŒãã¹ã«äžé©åãªåœ¢åŒã® UTF-8 ãéä¿¡ããå¯èœæ§ããããŸãã ãã®ããŒã¿ãé©åãªåœ¢åŒã§ãããã®ããã«æäœãããå Žåãã¢ããªã±ãŒã·ã§ã³ã«ãšã©ãŒãã»ãã¥ãªã㣠ããŒã«ãçºçããå¯èœæ§ããããŸãã UTF-8 ã®ããŒã¿ãæ€èšŒããã«ã¯ãEncoding.UTF8.GetString ã®ãããªã¡ãœããã䜿çšã§ããŸããããã¯ãåä¿¡ããŒã¿ã string ã«å€æãããšãã«æ€èšŒãå®è¡ããŸãã
é©åãªåœ¢åŒã®ãšã³ã³ãŒã
é©åãªåœ¢åŒã® Unicode ãšã³ã³ãŒããšã¯ãæç¢ºã«ããã€ãšã©ãŒãªãã§ Unicode ã¹ã«ã©ãŒå€ã®ã·ãŒã±ã³ã¹ã«ãã³ãŒãã§ãããã³ãŒãåäœã® string ã®ããšã§ãã é©åãªåœ¢åŒã®ããŒã¿ã¯ãUTF-8ãUTF-16ãããã³ UTF-32 éã§èªç±ã«ãã©ã³ã¹ã³ãŒãã§ããŸãã
ãããšã³ã³ãŒã ã·ãŒã±ã³ã¹ãé©åãªåœ¢åŒã§ãããã©ããã¯ãã³ã³ãã¥ãŒã¿ãŒã®ã¢ãŒããã¯ãã£ã®ãšã³ãã£ã¢ã³ã«ã¯é¢ä¿ãããŸããã äžé©åãªåœ¢åŒã® UTF-8 ã·ãŒã±ã³ã¹ã¯ãããã° ãšã³ãã£ã¢ã³ã®ã³ã³ãã¥ãŒã¿ãŒã§ããªãã« ãšã³ãã£ã¢ã³ã®ã³ã³ãã¥ãŒã¿ãŒã§ããåãããã«äžé©åãªåœ¢åŒã«ãªããŸãã
äžé©åãªåœ¢åŒã®ãšã³ã³ãŒãã®äŸããæ¬¡ã«ããã€ã瀺ããŸãã
UTF-8 ã§ã¯ãã·ãŒã±ã³ã¹
[ 6C C2 61 ]ã¯äžé©åãªåœ¢åŒã§ããC2ã®åŸã«61ãé 眮ããããšã¯ã§ããªãããã§ããUTF-16 ã§ã¯ãã·ãŒã±ã³ã¹
[ DC00 DD00 ](ãŸãã¯ãC# ã§ã¯ãstring"\udc00\udd00") ã¯äžé©åãªåœ¢åŒã§ããäžäœãµãã²ãŒãDC00ã®åŸã«å¥ã®äžäœãµãã²ãŒãDD00ãé 眮ããããšãã§ããªãããã§ããUTF-32 ã§ã¯ãã·ãŒã±ã³ã¹
[ 0011ABCD ]ã¯äžé©åãªåœ¢åŒã§ãã0011ABCDã Unicode ã¹ã«ã©ãŒå€ã®ç¯å²å€ã§ããããã§ãã
.NET ã§ã¯ãstring ã€ã³ã¹ã¿ã³ã¹ã«ã¯ã»ãšãã©åžžã«é©åãªåœ¢åŒã® UTF-16 ããŒã¿ãå«ãŸããŸãããä¿èšŒãããŠããããã§ã¯ãããŸããã
string ã€ã³ã¹ã¿ã³ã¹å
ã«äžé©åãªåœ¢åŒã® UTF-16 ããŒã¿ãäœæããæå¹ãª C# ã³ãŒãããæ¬¡ã®äŸã«ç€ºããŸãã
äžé©åãªåœ¢åŒã®ãªãã©ã«:
const string s = "\ud800";ãµãã²ãŒããã¢ãåå²ããéšåæåå:
string x = "\ud83e\udd70"; // "ð¥°" string y = x.Substring(1, 1); // "\udd70" standalone low surrogate
Encoding.UTF8.GetString ã®ãã㪠API ã䜿çšããå Žåãäžé©åãªåœ¢åŒã® string ã€ã³ã¹ã¿ã³ã¹ãè¿ãããããšã¯ãããŸããã
Encoding.GetString ããã³ Encoding.GetBytes ã¡ãœããã§ã¯ãå
¥åã«å«ãŸããäžé©åãªåœ¢åŒã®ã·ãŒã±ã³ã¹ãæ€åºãããåºåãçæããéã«æåã®çœ®æãå®è¡ãããŸãã ããšãã°ãEncoding.ASCII.GetString(byte[]) ãžã®å
¥åã«é ASCII ãã€ã (U+0000..U+007F ã®ç¯å²å€) ãå«ãŸããŠããå Žåãè¿ããã string ã€ã³ã¹ã¿ã³ã¹ã«ã¯ '?' ãæ¿å
¥ãããŸãã
Encoding.UTF8.GetString(byte[]) ã«ãã£ãŠè¿ããã U+FFFD REPLACEMENT CHARACTER ('ᅵ') ã€ã³ã¹ã¿ã³ã¹ã§ã¯ãäžé©åãªåœ¢åŒã® UTF-8 ã·ãŒã±ã³ã¹ã string ã«çœ®ãæããããŸãã 詳现ã«ã€ããŠã¯ãUnicode æšæºã®ãã»ã¯ã·ã§ã³ 5.22 ããã³ 3.9 ãåç
§ããŠãã ããã
çµã¿èŸŒã¿ã® Encoding ã¯ã©ã¹ã¯ãäžé©åãªåœ¢åŒã®ã·ãŒã±ã³ã¹ãæ€åºããããšãã«ãæåã®çœ®æãå®è¡ããã®ã§ã¯ãªããäŸå€ãã¹ããŒããããã«æ§æããããšãã§ããŸãã ãã®æ¹æ³ã¯ãæåã®çœ®æãåãå
¥ããããªãå¯èœæ§ããããã»ãã¥ãªãã£ã«åœ±é¿ããã¢ããªã±ãŒã·ã§ã³ã§ãã䜿çšãããŸãã
byte[] utf8Bytes = ReadFromNetwork();
UTF8Encoding encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
string asString = encoding.GetString(utf8Bytes); // will throw if 'utf8Bytes' is ill-formed
çµã¿èŸŒã¿ã® Encoding ã¯ã©ã¹ã®äœ¿ç𿹿³ã«ã€ããŠè©³ããã¯ãã.NET ã§æåãšã³ã³ãŒãã£ã³ã° ã¯ã©ã¹ã䜿çšããæ¹æ³ããã芧ãã ããã