เครื่องคำนวณความยาวของสตริง
เมื่อคุณวางข้อความเข้าไป เครื่องมือนี้จะแสดงความยาวของข้อความในสี่รูปแบบที่แตกต่างกัน ได้แก่ .length ในรูปแบบ JavaScript (หน่วยรหัส UTF-16), จุดรหัส Unicode, กลุ่มกราฟีม (สิ่งที่ผู้ใช้รับรู้ว่าเป็นตัวอักษรเดียว), และไบต์ UTF-8 (สิ่งที่คอลัมน์ในฐานข้อมูลของคุณเก็บจริง) ค่าเหล่านี้อาจไม่ตรงกันสำหรับข้อความที่มีอีโมจิ สัญลักษณ์ธง หรือเครื่องหมายรวมตัว และความไม่ตรงกันนี้เองคือสาเหตุของบั๊กจำนวนมาก
ความยาวของสตริงในสี่ความหมาย
-
1
หน่วยรหัส UTF-16
ค่าที่ `str.length` ส่งกลับในภาษา JavaScript โดยใช้ค่า 1 สำหรับตัวอักษรส่วนใหญ่ และค่า 2 สำหรับรหัสใดๆ ที่อยู่นอกเหนือจากชุด U+FFFF (เช่น อีโมจิ หรือตัวอักษรโบราณ)
-
2
จุดรหัส (code points)
หนึ่งจุดต่อสเกลาร์ยูนิโค้ดหนึ่งตัว อีโมจินับเป็น 1 ต่อหนึ่งตัว ส่วนลำดับ ZWJ นับได้หลายจุด
-
3
กลุ่มกราฟีม (Grapheme clusters)
สิ่งที่ผู้ใช้เรียกว่า “ตัวอักษรเดียว” นั้น โดย `🇺🇸` มีจำนวนจุดรหัส 2 แต่เป็นกราฟีมเพียงหนึ่งตัว ส่วน `n̈` ก็มีจำนวนจุดรหัส 2 เช่นกัน แต่ก็เป็นกราฟีมเพียงหนึ่งตัวเท่านั้น
-
4
ไบต์ของ UTF-8
ข้อมูลที่ฐานข้อมูลของคุณจัดเก็บ: ASCII = 1 ไบต์ต่อชุด; รูปแบบมาตรฐานของยุโรป = 2 ไบต์; CJK = 3 ไบต์; และอีโมจิส่วนใหญ่ = 4 ไบต์
ตัวอย่าง
| สตริง | ความยาวของสตริง (JS .length) | จำนวนจุดในรหัส | กราฟีม | ไบต์ตามมาตรฐาน UTF-8 |
|---|---|---|---|---|
hello |
5 | 5 | 5 | 5 |
café |
4 | 4 | 4 | 5 |
😀 |
2 | 1 | 1 | 4 |
🇺🇸 |
4 | 2 | 1 | 8 |
👨👩👧 (ครอบครัว) |
8 | 5 | 1 | 18 |
n̈ (n + เครื่องหมายสองจุดข้างบน) |
2 | 2 | 1 | 3 |
ทำไมตัวเลขจึงแตกต่างกัน
สตริงใน JavaScript อยู่ในรูปแบบ UTF-16 ดังนั้นจุดรหัสที่สูงกว่า U+FFFF จะถูกจัดเก็บเป็นคู่แทน (surrogate pair) ซึ่งประกอบด้วยหน่วยรหัส UTF-16 สองตัว จึงทำให้ "😀".length === 2 ผู้ใช้มักไม่ชอบเรื่องนี้ เพราะพวกเขามองว่า 😀 เป็นตัวอักษรเพียงตัวเดียว
กราฟีมไปไกลกว่านั้นอีก ธงของประเทศประกอบด้วยจุดรหัสบ่งชี้ภูมิภาคสองจุด แต่ผู้ใช้มองเห็นเป็นธงเดียว เช่น "🇺🇸".length === 4 ใน JavaScript ซึ่งฟังดูไร้เหตุผล แต่ก็เป็นเช่นนั้นจริง หากต้องการวนซ้ำทีละกราฟีม ให้ใช้ Intl.Segmenter (แบบสมัยใหม่) หรือไลบรารี grapheme-splitter หรือจัดการเองด้วยมือ
ไบต์ UTF-8: สิ่งที่ฐานข้อมูลของคุณจัดเก็บ
สำหรับคอลัมน์ชนิด VARCHAR(255):
- ใน MySQL
utf8(จริง ๆ คือ utf8mb3) ค่า 255 หมายถึงจำนวนไบต์ ส่วนcaféใช้ 5 ไบต์ จึงเก็บได้ 51 ชุด - ใน MySQL
utf8mb4(UTF-8 จริงที่รวมอีโมจิ) ยังคงนับเป็นไบต์ แต่การเข้ารหัสรองรับลำดับยาว 4 ไบต์ - ใน Postgres
VARCHAR(255)ค่า 255 หมายถึงจำนวนตัวอักษร (จุดรหัส) ไม่ใช่ไบต์ - ใน SQL Server
VARCHARค่าจะต่างกันไปตามการเรียงลำดับ (collation) ส่วนNVARCHARจะนับหน่วย UCS-2 ขนาด 2 ไบต์
หากคุณกำหนดขนาดฟิลด์ในฐานข้อมูลตามจำนวนตัวอักษรที่ผู้ใช้มองเห็น ให้ใช้ค่า “จำนวนไบต์ × 4” เพื่อความปลอดภัยในคอลัมน์ UTF-8 เพราะแต่ละกราฟีมอาจใช้พื้นที่ได้ถึง 4 ไบต์ต่อจุดรหัส และลำดับ ZWJ ยังเพิ่มขึ้นอีก
การนับตัวอักษรแบบ Twitter
Twitter นับทวีตตามกฎเฉพาะของตน คือนับเป็นจุดรหัส แต่อีโมจิและอักษรภาพ CJK จะนับเป็น 2 ทวีตที่เป็น ASCII ล้วนสามารถมีได้ถึง 280 ตัวอักษร ส่วนทวีตที่ใช้อีโมจิ 140 ตัวจะถึงเพดานที่ 140 “ตัวอักษร”
การนับ SMS: GSM 7 บิตได้ 160 ตัวอักษร หากมีตัวอักษรที่ไม่ใช่ GSM (เช่น á, é, ñ หรืออีโมจิ) แม้แต่ตัวเดียว การเข้ารหัสจะเปลี่ยนไปเป็น UCS-2 และความยาวข้อความจะลดลงเหลือ 70 ตัวอักษร
การใช้งานจริง
- การกำหนดขนาดคอลัมน์ในฐานข้อมูล, ตรวจสอบจำนวนไบต์ก่อนเขียนสคริปต์ย้ายฐานข้อมูล (migration)
- การบังคับใช้โควตา API, API ส่วนใหญ่นับเป็นไบต์ ไม่ใช่ตัวอักษร
- การตรวจสอบฟอร์ม, แสดงจำนวนตัวอักษรที่ถูกต้องตรงกับความคาดหวังของผู้ใช้ (กราฟีม)
- การดีบักประสิทธิภาพ, ทำไม regex นี้จึงวนซ้ำช้า? เพราะข้อมูลขาเข้ายาวกว่าในหน่วยรหัสถึง 3 เท่าเมื่อเทียบกับในหน่วยกราฟีม
คำถามที่พบบ่อย
อีโมจิตัวนี้เป็นลำดับ ZWJ ที่รวมจุดรหัสหลายจุดเข้าด้วยกัน (เช่น อีโมจิครอบครัวมีจุดรหัส 7 จุด) Twitter นับว่าเป็น 2 ตัวอักษรตามกฎน้ำหนักของ Unicode ขณะที่โปรแกรมแก้ไขข้อความของคุณแสดงเป็นกราฟีมเพียงตัวเดียว ทั้งสองวิธีถูกต้องในเชิงเทคนิค เพียงแต่วัดคนละสิ่งกัน
ในฐานข้อมูล UTF-8 เพื่อความปลอดภัย ควรเผื่อ 4 ไบต์ต่อหนึ่งตัวอักษรที่คาดไว้ ฟิลด์ที่รองรับ 100 ตัวอักษร (กราฟีม) ควรเป็น VARCHAR(400) ไบต์ หรือถ้าฐานข้อมูลนับเป็นตัวอักษรอย่าง Postgres ก็ใช้ VARCHAR(100) พร้อมกำหนดชุดอักขระ (charset) ให้เหมาะสม
ใน JavaScript ขึ้นอยู่กับรูปแบบการทำให้เป็นบรรทัดฐาน (normalization) รูปแบบ NFC ที่รวมกัน (U+00E1) มีความยาวเท่ากับ 1 ส่วนรูปแบบ NFD ที่แยกออก (U+0061 + U+0301) มีความยาวเท่ากับ 2 ตัวอักษรที่แสดงเหมือนกัน แต่ลำดับไบต์ต่างกัน
อีโมจิที่เกี่ยวข้องกับครอบครัวและอาชีพเป็นลำดับตัวอักษรยาวแบบ ZWJ หากฟอนต์ไม่รองรับอย่างเต็มรูปแบบ จะแสดงแต่ละรหัสเป็นกราฟิกแยกต่างหาก ทำให้ 👨💻 กลายเป็น 👨 + 💻 การอัปเกรดฟอนต์ในระบบปฏิบัติการจะแก้ไขปัญหานี้ได้
เครื่องมือที่เกี่ยวข้อง
เครื่องแปลงตัวเลขเป็นคำไทย
เขียนจำนวนไม่เกิน 18 หลักเป็นคำไทย หรือเขียนจำนวนบาทและสตางค์ตามค่าที่กรอกในเบราว์เซอร์ รองรับเลขอารบิกกับเลขไทยและไม่ปัดค่า
เครื่องมือสร้างตัวอักษรวงกลม
แปลงข้อความธรรมดาให้เป็นตัวอักษรวงกลม (Ⓐ Ⓑ Ⓒ) ที่คัดลอกแล้ววางลงในไบโอ Instagram, TikTok และ Discord ได้ มีทั้งตัวพิมพ์ใหญ่และตัวพิมพ์เล็กในวงกลม พร้อมตัวเลขในวงกลม โดยไม่ต้องใช้แอป
สัญลักษณ์ลูกศรสำหรับคัดลอก
คัดลอกลูกศร Unicode ที่ใช้บ่อยได้ในคลิกเดียว ทั้งแบบตรง สองเส้น ทแยง มีขอ วงกลม และสามเหลี่ยม สำหรับเอกสาร แชต และงานออกแบบ
สัญลักษณ์น้อยกว่าหรือเท่ากับ
คัดลอกสัญลักษณ์ ≤ และสัญลักษณ์เปรียบเทียบทางคณิตศาสตร์ที่เกี่ยวข้อง รวมถึง Unicode เอนทิตี HTML และการเขียน LaTeX สำหรับสเปรดชีต งานวิจัย และหน้าเว็บ
ตัวเข้ารหัสเอนทิตี HTML
แปลงอักขระ HTML ที่ต้องระวังห้าตัวเป็นเอนทิตีแบบคงที่ หรือถอดรหัสเอนทิตีเป็นข้อความในเบราว์เซอร์ของคุณ
เครื่องกำเนิดข้อความแบบวงกลม
แปลงข้อความธรรมดาเป็นอักขระ Unicode แบบวงกลม รูปแบบโครงร่าง เติม และวงกลมตัวเลขสำหรับประวัติโซเชียล แชท และเอกสาร
เครื่องมือนี้มีให้บริการในภาษาอื่น
- 文字列長計算ツール [JA]
- Stränglängdsberäknare [SV]
- Stringlengteberekenaar [NL]
- مقياس طول السلسلة النصية [AR]
- 문자열 길이 계산기 [KO]
- Kalkulator Panjang String [ID]
- Calculadora de Comprimento de String [PT]
- Zeichenlängenrechner [DE]
- Calculadora de Longitud de Cadenas [ES]
- Công cụ tính chiều dài chuỗi ký tự [VI]
- Calculateur de longueur de chaîne [FR]
- Kalkulator długości ciągu znaków [PL]
- Калькулятор длины строки [RU]
- Dize Uzunluğu Hesaplayıcı [TR]
- 字符串长度计算器 [ZH]
- String Length Calculator [EN]
- Calcolatore della lunghezza della stringa [IT]