Unicode in PHP

วันนี้มีปัญหากับ Twiki เพราะมันตัด string ภาษาไทยเหลือนิดเดียว ในขณะที่ภาษาอังกฤษล้วนได้ยาวกว่าโข

ปัญหานี้เกิดกับโปรแกรมที่ใช้รหัสอักขระแบบ Unicode ซึ่งรวม SMS ในมือถือด้วย

การเข้ารหัสตัวอักษรแบบ UTF-8 นั้นจะให้ตัวละติน 128 ตัวแรกตาม ASCII ใช้แค่ 1 byte (โดยให้เหตุผลว่าเป็นตัวที่ใช้บ่อย) ส่วนที่เหลือจะใช้ 3 byte (Basic Multilingual Plane ภาษาไทยอยู่ในหมวดนี้) และตัวอักษรพิสดาร เช่น ตัวจีนแบบที่ไม่ค่อยมีคนใช้ (Supplementary Multilingual Plane) จะนับ 4 byte (อ่าน: UTF-8, Mapping of Unicode characters)

Note: Unicode มีการเข้ารหัสอีกหลายแบบ (เช่น UTF-16) เพียงแต่ UTF-8 ได้รับความนิยมสูงสุดในการแลกเปลี่ยนข้อมูลระหว่างโปรแกรม (UTF-16 นิยมใช้ภายในโปรแกรม)

สำหรับ CMS อย่าง Twiki หรือ Drupal คงจะโทษตัว CMS ไม่ได้ เพราะสาเหตุมาจาก PHP5 ไม่สนับสนุน Unicode แบบ native (อ่าน) ต้องใช้ MBString extension เข้าช่วย

ปัญหานี้จะถูกแก้ไขใน PHP6 (อ่าน) ประเด็นสำคัญๆ ก็อย่างการเปิด Unicode on เป็น default, การผนวก ICU เข้ามา (สำหรับตัดคำและงานอื่นๆ) หรือไม่ เป็นต้น

Comments

สำหรับคนทำ Natural Language Processing คงไม่ได้รับผลกระทบจากการเปลี่ยนไปเปลี่ยนมาของมาตรฐานการเข้ารหัสตัวอักษรมากนัก เพราะเข้าใจว่าไม่ว่าจะใช้รหัสภาษาไทยแบบ รหัสเกษตร, รหัส สมอ., Windows-874, TIS-620 หรือตระกูล Unicode ก็ตาม คนทำ Natural Lanaguage Processing ก็จะสามารถ markup พยัญชนะ, สระ, วรรณยุกต์ และเครื่องหมายวรรคตอน เอาไว้ใน character list ได้อยู่แล้ว

แต่ถ้าตกลงกันได้ทั้งโลกอินเตอร์เน็ตว่าจะใช้ UTF-16 ให้หมดก็น่าจะดี เพราะการทำ migration กับ conversion ข้อมูลจากการเข้ารหัสแบบนึง ไปเป็นการเข้ารหัสอีกแบบนึง มันสร้างความปวดเศียรเวียนเกล้าเหมือนกันครับ T-T

PeeTai: สาย NLP น่าจะอยู่คนละ layer กับเรื่องพวกนี้ครับ คือไม่สนใจระดับชั้น encoding มองข้ามช็อตถึงตอน decode แล้วเหลือแต่ character ใน data type จริงๆ มากกว่า

จริง ๆ มันก็มีปัญหาอยู่บ้าง
ตอนจะตรวจจับว่าเอกสารนั้นใช้ charset อะไร
โดยเฉพาะกรณี plain text ที่ไม่ได้มี metadata ระบุ charset มาด้วย
เช่นกรณีทำ web crawling

แต่หลังจากตรวจจับได้แล้ว ก็ไม่น่าจะมีปัญหาอะไรมากแล้ว

ปัญหาที่จะยังมีอยู่ ภาษาไทยอาจจะไม่มากนัก แต่ภาษาในยุโรปหลายอันมีก็คือ
บางที "ตัวอักษร" เดียวกัน มันเขียนได้หลายแบบ
ก็ต้องมา preprocess กันก่อนเข้ากระบวนการ NLP
เช่น
ตัว ß ในภาษาเยอรมัน จะเขียนเป็น ss ก็ได้ (โดยเฉพาะกรณีแป้นพิมพ์ดีดมันไม่มี หรือใช้ ASCII charset)
หรือ ü จะเขียนเป็น ue ก็ได้ หรือจะเขียนเป็น u กับตัวอักษร .. ประกอบกันก็ได้ (รวมกันเป็นสองตัว)
ตอน preprocess ก็ต้อง normalize พวกนี้ให้ออกมาเป็นแบบเดียวกันหมดก่อน จะได้ประมวลผลต่อง่าย ๆ

แต่ทีนี้ ก็ไม่ใช่ว่าทุก ss จะเท่ากับ ß บางคำมันก็ตามตัวเลย ห้ามแปลง
แล้วจะทำไง ?
-- นี่ก็เป็นปัญหา - เป็นปัญหาในระดับ encoding เลย

สำหรับกรณีการเขียนโปรแกรม
ก็อาจจะมีปัญหาบ้าง ถ้าภาษาโปรแกรมนั้น ๆ ไม่ได้รองรับ Unicode
อย่างถ้าเป็นภาษาบน JVM หรือ .NET ก็สบาย (Cocoa ก็ด้วย)
อย่างไรก็ตาม ปัญหานี้แก้ไขได้ไม่ยาก ถ้าจะทำจริง ๆ ก็เพียงเขียนผ่าน wrapper/library อะไรซักตัว

หรือถ้าจะสะดวกกว่านั้น บางภาษาก็เตรียมฟังก์ชั่นที่ซับซ้อนขึ้นมาให้ด้วย
เช่นกรณี normalization ที่ว่าไปด้านบน ICU มี class/method ที่ทำตรงนี้ให้
ซึ่งบางส่วนรวมได้อยู่ใน Java standard library แล้ว
http://java.sun.com/javase/6/docs/api/java/text/Normalizer.html
(ใน .NET ก็น่าจะมี)

เรื่องให้ใช้ UTF-16 ทั้งหมดในอินเทอร์เน็ตคงยาก
เพราะหลายโปรโตคอล ยังอิง 8-bit อยู่ - UTF-8 มันเลยเกิดขึ้นมาไง

เซียน NLP ตัวจริงมาแถลงเลยวุ้ย

Add new comment