บทความก่อนหน้า
String format และ Lua pattern
string.format()
เป็นฟังก์ชันจัดรูปแบบข้อความคล้ายกับ sprintf ในภาษา C, C++, Perl, PHP, R, Ruby หรือ % operator ใน Python, Ruby โดยมีรูปแบบของการจัดรูปแบบข้อความดังนี้
%[flags][ความกว้าง][.จำนวนทศนิยม]รูปแบบ
flags ได้แก่
+ แสดงเครื่องหมาย + หน้าตัวเลขบวก
เว้นวรรค แสดงช่องว่างหน้าตัวเลขบวก
- ใช้คู่กับ ความกว้าง แสดงตัวเลขชิดซ้าย
0 ใช้คู่กับ ความกว้าง แสดง 0 แทนช่องว่าง
# ใช้คู่กับ รูปแบบ x หรือ X แสดง 0x หรือ 0X หน้าตัวเลขฐาน 16
ใช้คู่กับ รูปแบบ o แสดง 0 หน้าตัวเลขฐาน 8
ใช้คู่กับ รูปแบบ e หรือ E หรือ f บังคับแสดงจุดทศนิยม
ใช้คู่กับ รูปแบบ g หรือ G บังคับแสดงจุดทศนิยมและไม่ตัด 0 ทิ้ง
ความกว้าง ใช้กำหนดจำนวนตัวอักษรทั้งหมดที่จะแสดง
ถ้าข้อมูลมีจำนวนตัวอักษรเกิน ความกว้าง จะแสดงตามจำนวนตัวอักษรของข้อมูล
ถ้าข้อมูลมีจำนวนตัวอักษรน้อยกว่า ความกว้าง จะเติมช่องว่างด้านซ้ายข้อมูลเว้นแต่มี flags - จะเติมช่องว่างด้านขวาแทน
.จำนวนทศนิยม ใช้ระบุจำนวนทศนิยมที่จะแสดงใน รูปแบบ f, e, E, g, G
ถ้าใส่ . แต่ไม่มีตัวเลขจะเป็นการปัดเศษทศนิยม ( round ) เป็นจำนวนเต็ม
รูปแบบ ได้แก่
s แสดงข้อมูลเป็นแบบตัวอักษร
q แสดงข้อมูลตัวอักษรพร้อมใส่ \" \" ครอบถ้าในข้อความมี " จะแปลงเป็น \\\" ให้
c แปลงตัวเลขเป็นตัวอักษรรหัส ASCII ( 0-255 )
d, i แสดงข้อมูลตัวเลขจำนวนเต็มฐานสิบ ( 0x4d2 -> "1234", "123.0" -> "123" )
u แสดงข้อมูลตัวเลขจำนวนเต็มฐานสิบแบบไม่มีเครื่องหมาย ( -1 -> 18446744073709551615 )
x แสดงข้อมูลตัวเลขจำนวนเต็มฐานสิบหกแบบอักษรตัวเล็ก ( 1234 -> "4d2" )
X แสดงข้อมูลตัวเลขจำนวนเต็มฐานสิบหกแบบอักษรตัวใหญ่ ( 1234 -> "4D2" )
o แสดงข้อมูลตัวเลขจำนวนเต็มฐานแปด ( 1234 -> "2322" )
f แสดงข้อมูลตัวเลขทศนิยมฐานสิบ ( 2 -> "2.000000", 1.234e+02 -> "123.4000" )
e แสดงข้อมูลตัวเลขทศนิยมรูปแบบวิทยาศาสตร์ฐานสิบสัญลักษณ์เลขยกกำลังตัวเล็ก ( 123 -> "1.230000e+02" )
E แสดงข้อมูลตัวเลขทศนิยมรูปแบบวิทยาศาสตร์ฐานสิบสัญลักษณ์เลขยกกำลังตัวใหญ่ ( 123 -> "1.230000E+02" )
g แสดงข้อมูลตัวเลขทศนิยมแบบสั้น
ทศนิยมรูปแบบวิทยาศาสตร์ฐานสิบสัญลักษณ์เลขยกกำลังตัวเล็กแบบสั้น
หรือจำนวนเต็มฐานสิบ ( ตัดศูนย์ทิ้ง 12.300 -> "12.3" )
G แสดงข้อมูลตัวเลขทศนิยมแบบสั้น
ทศนิยมรูปแบบวิทยาศาสตร์ฐานสิบสัญลักษณ์เลขยกกำลังตัวใหญ่แบบสั้น
หรือจำนวนเต็มฐานสิบ ( ตัดศูนย์ทิ้ง 1.2300e+01 -> "1.23E+01" )
a แสดงข้อมูลตัวเลขทศนิยมฐานสิบหกแบบอักษรตัวเล็ก ( 1.234 -> "0x1.3be76c8b43958p+0" )
A แสดงข้อมูลตัวเลขทศนิยมฐานสิบหกแบบอักษรตัวใหญ่ ( 1.234 -> "0X1.3BE76C8B43958P+0" )
% แสดง %
ตัวอย่าง
print(string.format("Hello%8s. PI=%s (%-6.2f) (%03.f)","World",math.pi,math.pi,math.pi))
----> "Hello World. PI=3.1415926535898 (3.14 ) (003)"
print(("Hello%-8s. PI=%e (%10f) %% (% .3f)%s"):format("World",math.pi,math.pi,math.pi,"%"))
----> "HelloWorld . PI=3.141593e+00 ( 3.141593) % ( 3.142)%"
Lua pattern
คล้ายกับ Regular Expression ที่มีในหลายโปรแกรมแต่เป็นฉบับย่อสำหรับค้นหาข้อความที่มีรูปแบบตรงกับ pattern ที่กำหนดสำหรับใช้กับ string.find(), string.match(), string.gsub(), string.gmatch() มีรูปแบบดังนี้
^ ตัวอักขระที่ตามหลั้ง ^ จะต้องเป็นอักษรตัวแรกของข้อความ ( "^a" --> "abb" ตรง, "bab" ไม่ตรง ) $ ตัวอักขระก่อน $ จะต้องเป็นตัวสุดท้ายของข้อความ ( "b$" --> "bab" ตรง, "bba" ไม่ตรง ) . ตัวอักขระอะไรก็ได้ ( "^a..b$" --> "ac b" ตรง, "axb" ไม่ตรง, "a2rdsb" ไม่ตรง ) %a ตัวอักษร a-z A-Z ( "3%ab" --> "3Xb" ตรง, "3.b" ไม่ตรง, "3*b" ไม่ตรง ) %A ตัวอักขระทุกตัวที่ไม่ใช่ a-z A-Z ( "3%Ab" --> "3#b" ตรง, "3 b" ตรง, "3eb" ไม่ตรง ) %c ตัวอักษรที่เป็นอักขระควบคุม ( control characters ) เช่น \n ( new line หรือ line feed ) \t ( tab ) \e ( escape ) %C ตัวอักษรทุกตัวที่ไม่ใช่อักขระควบคุม %d ตัวเลข 0-9 %D ตัวอักขระทุกตัวที่ไม่ใช่ตัวเลข %g ( Lua 5.2 ขึ้นไป ) ตัวอักขระที่แสดงผลได้ในรหัส ASCII ( printable characters เช่นตัวอักษร ตัวเลข เครื่องหมายวรรคตอน สัญลักษณ์ต่างๆ ) ทุกตัวยกเว้นตัวเว้นวรรค ( space ) %G ( Lua 5.2 ขึ้นไป ) ตัวอักขระที่ไม่ใช่ printable characters รวมถึง space %l ตัวอักษรตัวเล็ก a-z %L ตัวอักขระที่ไม่ใช่ a-z %p เครื่องหมายวรรคตอนและสัญลักษณ์ ( '".,:;|/\~!?@#$%^&(){}[]+-*=<>_ ) %P ตัวอักขระที่ไม่ใช่เครื่องหมายใน %p %s เว้นวรรค %S อักขระทุกตัวที่ไม่ใช่เว้นวรรค %u ตัวอักษรตัวใหญ่ A-Z %U ตัวอักขระที่ไม่ใช่ A-Z %w ตัวอักษรและตัวเลข ( alphanumeric characters a-z A-Z 0-9 ) %W ตัวอักขระที่ไม่ใช่ alphanumeric character %x ตัวเลขฐานสิบหก ( hexadecimal digit a-f A-F 0-9 ) %X ตัวอักขระที่ไม่ใช่เลขฐานสิบหก %z ตัวอักขระ "\000" [set] ตัวอักขระตัวใดตัวหนึ่งที่อยู่ใน set ( "[a-zA-Z]" เหมือนกับ "%a", "[0-7]" --> ตัวเลขฐานแปด, "[cD]" --> "c" หรือ "D" ) [^set] ตัวอักขระที่ไม่อยู่ใน set ( "[^A-Z0-9a-z]" เหมือนกับ "%W" ) %f[set] frontier pattern หาอักขระที่อยู่ระหว่างอักขระที่ไม่อยู่ใน set กับอักขระที่อยู่ใน set ( ("asdf1234"):gsub("%f[%d]","@") --> "asdf@1234" ) %bxy ตัวอักขระทุกตัวเริ่มตั้งแต่ x ตัวแรกจนถึง y ตัวสุดท้าย ( ("asdf{asde2354{} 45az }"):match("%b{}") --> "{asde2354{} 45az }" ) (pattern) capture pattern หาข้อความที่ตรงกับ pattern ใน () แล้วเก็บไว้อ้างถึงภายหลังได้ด้วย %n โดย n เป็นตัวเลขแสดงลำดับที่ของ () ( ("abcde"):gsub("(%a)c(%a)"," %2%1 ") --> "a db e" ) แต่ถ้าข้างใน () ไม่ได้กำหนด pattern จะคืนค่าเป็นตำแหน่งอักขระแทน ( ("abcde"):gsub("()c()"," %2xx%1 ") --> "a 4xx3 e" ; a->1,b->2,c->3,d->4,e->5 ) %อัขระพิเศษ ใช้สำหรับต้องการหมายถึงตัวอักขระพิเศษที่ใช้ใน pattern เช่น ^ $ . % ( ) [ + - * ? ? บอกจำนวนอักขระที่อยู่หน้า ? จำนวน 1 อักขระหรือไม่มีเลย + บอกจำนวนอักขระที่อยู่หน้า + จำนวน 1 อักขระขึ้นไป * บอกจำนวนอักขระที่อยู่หน้า * จำนวน 0 อักขระขึ้นไป - บอกจำนวนอักขระที่อยู่หน้า - จำนวน 0 อักขระขึ้นไป ( จำนวนอักขระที่น้อยที่สุด )
ASCII กับ Unicode
เดิมอักขระในคอมพิวเตอร์มีแค่ตัวเลข ตัวอักษรภาษาอังกฤษ สัญลัษณ์เครื่องหมาย และอักขระควบคุม ซึ่งทั้งหมดใช้แค่ 1 byte ( 8 bits 00000000 ถึง 11111111 หรือ 0 ถึง 255 ) ก็เพียงพอโดยใช้รหัสแค่ 0-127 และส่วนที่เหลือสำรองไว้ใช้เป็นรหัสอักษรของภาษาท้องถิ่น โดยรหัสอักขระที่ใช้เรียกกันว่ารหัส ASCII ต่อมาเมื่อมีความต้องการให้รองรับกับภาษานานาชาติจึงได้มีการออกมาตรฐาน Unicode ขึ้นได้แก่ UTF-8, UTF-16, UTF-32 เป็นต้น
ในภาษา Lua นั้นไม่ได้รองรับ Unicode จนในรุ่น 5.3 ได้เพิ่มการรองรับ UTF-8 บางส่วนในมอดูล utf8 แต่ในส่วนของ pattern และในมอดูล string ยังถือว่าแต่ละอักขระใช้ 1 byte อยู่ ส่วน UTF-8 นั้นที่รหัส 0-191 ใช้ 1 byte จากนั้นจะเพิ่มทีละ byte ตามตารางในลิงค์ข้างบนโดย byte แรกเริ่มที่ 192 ใช้ 2 bytes, 224 ใช้ 3 bytes และ 240 ใช้ 4 bytes ตามลำดับแต่ละ byte ที่เพิ่มขึ้นมาจะใช้รหัสตั้งแต่ 0-191
local text1 = "hello"
for char in text1:gmatch(".") do
print(char)
end
--[[ ผลลัพธ์
H
e
l
l
o
]]
local text2 = "ครับ"
for char in text2:gmatch(".") do
print(char)
end
--[[ ผลลัพธ์
\224 -- ค = \224\184\132 3 bytes
\184
\132
\224 -- ร = \224\184\163
\184
\163
\224 -- ั = \224\184\177
\184
\177
\224 -- บ = \224\184\154
\184
\154
]]
print(string.gsub("abcกdeขf", "[c-e]", "Z"))
--[[ ผลลัพธ์
abZกZZขf 3
]]
print(string.gsub("abcกdeขf", "ก", "Z"))
--[[ ผลลัพธ์
abcZdeขf 1
]]
print(string.gsub("abcกdeขf","[ก]","Z")) -- เท่ากับ [\129\184\224] --> \224 หรือ \129 หรือ \184
--[[ ผลลัพธ์
abcZZZdeZZ\130f 5 -- ข เท่ากับ \224\184\130
]]
print(string.gsub("abcกdeขf","\224\184[\129\130]","Z"))
--[[ ผลลัพธ์
abcZdeZf 2
]]
อักษรภาษาไทยจะใช้ 3 bytes เริ่มที่ \224\184\128 เป็นค่าว่าง "ก" เริ่มที่ \129 ถึง "ฮ" ที่ \174 "ฯ" ที่ \175 สระเริ่มที่ \176 ถึง \186 และ \224\185\128 ถึง \133 และอักขระอื่นๆ ไปจนถึง \166 ดังนั้นสำหรับตัวอักษรภาษาไทยเราสามารถใช้รูปแบบได้ดังนี้ "\224[\184\185][\128-\191]" สำหรับตัวอักขระแต่ละตัวและ "\224[\184\185][\128-\224]+" สำหรับข้อความ หากอยากใช้ unicode ใน pattern เต็มรูปแบบต้องเขียนฟังก์ชันใช้เองหรือติดตั้งมอดูลเสริมแทนเช่น lua-utf8 ซึ่งเป็น C module หรือ utf8 ที่เป็น pure Lua หรือไปใช้ pattern matching อื่นๆ
บทความถัดไป
ความคิดเห็น
แสดงความคิดเห็น