Data Warehouse

การจัดการกับสายอักขระ

ความยาวของสายอักขระ

สายอักขระอาจยาวเท่าใดก็ได้ การหาความยาวของสายอักขระทำได้เช่นเดียวกับลิสต์หรือทูเพิล คือใช้ฟังก์ชัน len

print(len('กขคงจ'))  # ได้ 5

สายอักขระอาจจะมีความยาวเป็นศูนย์ก็ได้ ซึ่งเขียนแทนด้วยเครื่องหมายคำพูดติดกันสองตัวโดยไม่มีอะไรข้างใน

print(len(''))  # ได้ 0

ช่องว่างจะถูกนับรวมความยาวด้วย ต่อให้ไม่ได้อยู่ตรงกลางก็ตาม

print(len(' '))  # ได้ 2

ภายในสายอักขระอักษรทุกตัวมีความยาวตัวละหน่วยเท่ากันหมด ไม่ว่าจะเป็นอักษรอะไรก็ตาม จะเป็นอักษร ASCII หรือไม่ก็ตาม
***ข้อนี้สำหรับไพธอน 3 ส่วนในไพธอน 2 จะแตกต่างออกไป รายละเอียด

การเข้าถึงสมาชิกของสายอักขระ

สายอักขระก็เป็นข้อมูลชนิดลำดับเช่นเดียวกับลิสต์หรือทูเพิล ดังนั้นสามารถเข้าถึงข้อมูลได้โดยใส่ลำดับสมาชิกในวงเล็บเหลี่ยม

a =  'bestuurdersaansprakelijkheidsverzekering'  
print(a[0])  # ได้ b  
print(a[-1])  # ได้ g  
print(a[int(len(a)/2)])  # ได้ l

สามารถเข้าถึงทีละหลายตัวด้วยการใช้ : เช่นกัน

a[29:40]  # ได้ verzekering  
a[0:40:2]  # ได้ 'bsuresasrkljhisezkrn'

การแก้ไขและเพิ่มข้อความในสายอักขระ
สายอักขระไม่สามารถแก้ไขข้อมูลอะไรได้ เช่นเดียวกับทูเพิล

b =  'เขาเป็นคนป่วย'  
b[9:11] =  'ร'  # ได้ TypeError: 'str' object does not support item assignment

แม้ว่าจะไม่สามารถแก้ไขข้อความข้างในได้ แต่ก็สามารถสร้างใหม่ทับตัวเก่าได้

b = b[:9]+'ร'+b[11:]  
print(b)  # ได้ เขาเป็นคนรวย

ส่วนการเพิ่มข้อความในสายอักขระก็ทำได้โดยเอาสายอักขระเดิมมาบวกกับสิ่งที่ต้องการเพิ่ม

c =  'เขาเป็นคนดี'  
c +=  'แต่พูด'  
print(c)  # ได้ เขาเป็นคนดีแต่พูด

การเปรียบเทียบสายอักขระ

สายอักขระสามารถนำมาทำการเปรียบเทียบเพื่อหาค่าความจริงเท็จได้โดย เมื่อใช้เครื่องหมาย == จะให้ค่าเป็นจริงต่อเมื่อเหมือนกันทุกตัวอักษร

print('J'  ==  'j')  # False เพราะพิมพ์เล็กกับพิมพ์ใหญ่ถือเป็นคนละตัว  
print('J'  ==  'j'.upper())  #True

เมื่อใช้เปรียบเทียบมากกว่า > หรือน้อยกว่า < จะเปรียบเทียบลำดับภายในยูนิโค้ดของอักษรนั้นทีละตัว โดยเลขที่มาก่อนถือว่าค่าน้อยกว่า หากเหมือนกันจึงจะพิจารณาตัวต่อไป

print('11'  >  '2')  # False เพราะเลข 1 เทียบกับ 2 ก่อน  
print('A'  >  'a')  # False เพราะตัวพิมพ์ใหญ่มาก่อนตัวพิมพ์เล็ก  
print('ü'  >  'z')  # True เพราะ z เป็น ASCII แต่ ü ไม่ใช่  
print('ม'  >  '美')  # False เพราะอักษรไทยมาก่อนอักษรจีนในยูนิโค้ด  
print('ア'  >  'あ')  # True เพราะฮิรางานะมาก่อนคาตาคานะ

การตัดช่องว่างหัวท้าย

ช่องว่างที่หัวท้ายของสายอักขระสามารถทำให้หายไปได้โดยใช้เมธอด strip

print(len(' แม่นแล้ว '))  # ได้ 13  
print(' แม่นแล้ว '.strip())  # ได้ แม่นแล้ว  
print(len(' แม่นแล้ว '.strip()))  # ได้ 8

หากต้องการตัดแค่หัวหรือท้ายอย่างเดียวก็ใช้ lstrip หรือ rstrip โดย lstrip จะตัดเฉพาะหัว ส่วน rstrip จะตัดเฉพาะท้าย

print(len(' แม่นแล้ว '.lstrip()))  # ได้ 11  
print(len(' แม่นแล้ว '.rstrip()))  # ได้ 10

การแบ่งและเชื่อมรวมสายอักขระ

สามารถแยกสายอักขระออกเป็นส่วนๆได้ด้วยเมธอด split โดยเมธอดนี้จะสร้างลิสต์ของสายอักขระแต่ละส่วนที่แยกได้ออกมา

โดยในการแยกจำเป็นต้องระบุว่าจะใช้สัญลักษณ์อะไรเป็นตัวแยก โดยใส่เป็นอาร์กิวเมนต์ในเมธอด เช่นหากต้องการให้แยกตามจุลภาพ ,

it =  'pasta, spaghetti, macaroni, lasagna, pizza'  
ita = it.split(', ')  
print(ita)  # ได้ ['pasta', 'spaghetti', 'macaroni', 'lasagna', 'pizza']

หากไม่ใส่อาร์กิวเมนต์อะไรลงในเมธอดเลยจะแยกตามช่องว่าง

fr =  'croissant baguette éclair macaron madeleine'  
fra = fr.split()  
print(fra)  # ได้ ['croissant', 'baguette', 'éclair', 'macaron', 'madeleine']

ในทางตรงข้ามมีเมธอดที่ชื่อ join เอาไว้ใช้รวมลิสต์ของสายอักขระเข้าเป็นสายอักขระอันเดียว

join นั้นถือเป็นเมธอดของสายอักขระโดยทำกับสายอักขระที่เป็นตัวคั่นแล้วมีอาร์กิวเมนต์เป็นลิสต์ของสายอักขระที่ต้องการรวม

วิธีการใช้อาจดูแล้วเข้าใจยากกว่า split อยู่หน่อยและอาจสับสนกันได้ ให้ดูตัวอย่างประกอบ

f = ['ยานี้ดี',  'กินแล้วแข็ง',  'แรงไม่มี',  'โรคภัยไข้เจ็บเบียดเบียน']  
g =  ''.join(f)  
print(g)  # ได้ ยานี้ดีกินแล้วแข็งแรงไม่มีโรคภัยไข้เจ็บเบียดเบียน

ลองเขียนโปรแกรมสำหรับเชื่อมโดยไม่ใช้ join ดูก็สามารถทำได้

f = ['ยานี้ดี',  'กินแล้วแข็ง',  'แรงไม่มี',  'โรคภัยไข้เจ็บเบียดเบียน']  
g =  ''  
for  s  in  f:  
g += s  
print(g)

ตัวเชื่อมอาจใช้เป็นอะไรก็ได้ เช่นเว้นวรรคก็ใช้ \n

h =  '\n'.join(['ooo','o o','ooo'])  
print(h)

จะได้สายอักขระที่มี ๓ บรรทัด

ooo  
o o  
ooo

สำหรับการแยกสายอักขระโดยใช้การขึ้นบรรทัดใหม่เป็นตัวแยกอาจใช้เมธอด splitlines เช่นลองใช้กับสายอักขระตัวเมื่อครู่

print(h.splitlines())  # ได้กลับมาเป็น ['ooo', 'o o', 'ooo']

หากต้องการแยกสายอักขระออกเป็นทีละตัวๆก็อาจทำได้ง่ายๆด้วยการใช้ list แปลงเป็นลิสต์ได้เลย

print(list('กลุ่มก้อน'))  # ได้ ['ก', 'ล', 'ุ', '่', 'ม', 'ก', '้', 'อ', 'น']

การเปลี่ยนตัวพิมพ์ใหญ่พิมพ์เล็ก

อักษรโรมันมักประกอบไปด้วยตัวพิมพ์เล็กและพิมพ์ใหญ่ ในภาษาไพธอนมีคำสั่งสำหรับเปลี่ยนข้อความในสายอักขระทั้งหมดเป็นพิมพ์เล็ก หรือพิมพ์ใหญ่ทั้งหมด นั่นคือใช้เมธอด upper และ lower

a =  'Die Flügel der Freiheit'  
print(a.upper())  # ได้ DIE FLÜGEL DER FREIHEIT  
print(a.lower())  # ได้ die flügel der freiheit

อักษรกรีกเองก็มีตัวพิมพ์เล็กพิมพ์ใหญ่ สามารถใช้ได้ด้วย

a =  'Αστρονομία'  
print(a.upper())  # ΑΣΤΡΟΝΟΜΊΑ  
print(a.lower())  # αστρονομία

***แต่ถ้าใช้ในไพธอน 2 มีข้อต้องระวัง อ่านรายละเอียด

สำหรับอักษรไทยไม่มีตัวพิมพ์เล็กพิมพ์ใหญ่จึงไม่มีผลอะไรกับเมธอดนี้

ลองเขียนโปรแกรมให้สร้างสายอักขระขึ้นใหม่โดยเปลี่ยนคำที่เป็นตัวพิมพ์เล็กทั้งหมดให้เป็นตัวพิมพ์ใหญ่สลับกับตัวพิมพ์เล็ก

a =  'pneumoultramicroscopicossilicovulcanoconioticozinhos'  
b =  ''  
for  i  in  range(0,len(a),2):  
b += a[i].upper()  
if(i<len(a)-1): b += a[i+1]  
print(b)  # ได้ PnEuMoUlTrAmIcRoScOpIcOsSiLiCoVuLcAnOcOnIoTiCoZiNhOs

การค้นหาข้อความที่ต้องการภายในสายอักขระ

การจะตรวจว่าข้อความสั้นๆที่เราต้องการค้นนั้นอยู่ภายในสายอักขระยาวๆหรือไม่สามารถใช้ in เช่น

'Essen'  in  'Sie sind das Essen und wir sind die Jäger'  # ได้ True

หากต้องการหาว่าคำที่ต้องการนั้นอยู่ในตำแหน่งไหนก็อาจทำการวนซ้ำเพื่อค้น เช่น

g =  'Sie sind das Essen und wir sind die Jäger'  
s =  'Essen'  
if(s  in  guren):  
for  i  in  range(len(g)):  
if(s  not in  g[i:]):  
print(i-1)  
break  
else:  print('ไม่พบคำที่ต้องการหา')

ผลลัพธ์จะได้ 13

อย่างไรก็ตามในภาษาไพธอนมีคำสั่งที่สามารถช่วยค้นหาได้โดยอัตโนมัติอยู่ นั่นคือ find

โครงสร้าง

สายอักขระ.find(คำที่ค้น, จุดเริ่มค้น, จุดสิ้นสุดการค้น)

โดยที่จุดเริ่มต้นและสิ้นสุดอาจใส่หรือไม่ใส่ก็ได้ ถ้าไม่ใส่ก็จะค้นทั้งหมด

g =  'Sie sind das Essen und wir sind die Jäger'  
print(g.find('Essen'))  # ได้ 13

หากค้นหาแล้วไม่พบ จะคืนค่า -1

print(g.find('der'))  # ได้ -1

กรณีที่มีคำที่ค้นอยู่ ๒ ตัวขึ้นไป จะขึ้นตำแหน่งของตัวแรก

print(g.find('sind'))  # ได้ 4

หากต้องการให้ค้นไล่มาจากด้านหลังให้ใช้เมธอด rfind

print(g.rfind('sind'))  # ได้ 27

กรณีที่กำหนดจุดเริ่มต้นและจุดสิ้นสุด ถ้าตัวที่ต้องการหาไม่อยู่ในขอบเขตก็จะหาไม่พบ

print(g.find('Sie',3))  # ได้ -1 (คือหาไม่พบ)  
print(g.find('die',2,35))  # ได้ 32  
print(g.find('die',2,32))  # ได้ -1 (คือหาไม่พบ)

นอกจากนี้ยังมีเมธอด index และ rindex ซึ่งก็ใช้ค้นหาเหมือนกัน แต่ความต่างคือหากค้นหาแล้วไม่เจอจะขึ้นขัดข้องแทนที่จะคืนค่า -1

print(g.index('Eren'))  # ได้ ValueError: substring not found

หากต้องการนับจำนวนคำที่ต้องการค้นว่ามีทั้งหมดกี่ตัวสามารถใช้เมธอด count

print(g.count('sind'))  # ได้ 2

ตรวจจุดเริ่มและจุดสิ้นสุด

ในการตรวจว่าข้อความขึ้นต้นและสิ้นสุดเป็นตัวที่ต้องการหรือไม่นั้น มีเมธอดเฉพาะที่สามารถใช้ได้ คือ startswith กับ endswith

โครงสร้าง

สายอักขระ.startswith(คำที่ค้น, จุดเริ่มค้น, จุดสิ้นสุดการค้น)  
สายอักขระ.endswith(คำที่ค้น, จุดเริ่มค้น, จุดสิ้นสุดการค้น)

ตัวอย่าง

a =  'verbrennungsanlage'  
print(a.startswith('ver'))  # ได้ True  
print(a.startswith('ver',3))  # ได้ False  
print(a.startswith('bren',3))  # ได้ True  
print(a.startswith('erb',1,7))  # ได้ True  
print(a.endswith('sanlage'))  # ได้ True  
print(a.endswith('nung',7))  # ได้ False  
print(a.endswith('san',3,14))  # ได้ True  
print(a.endswith('san',12,14))  # ได้ False

การแทนที่

สามารถค้นหาอักษรที่ต้องการแล้วเขียนทับได้โดยใช้เมธอด replace
โครงสร้าง

สายอักขระ.replace(ข้อความที่จะให้ถูกแทนที่,ข้อความที่จะนำไปแทน,จำนวนที่จะแทน)  

จำนวนที่แทนอาจไม่จำเป็นต้องใส่ก็ได้ หากไม่ใส่มีกี่ตัวก็จะถูกแทนหมด

ตัวอย่าง

v =  'ไก่จิกเด็กตายเด็กตายบนปากโอ่ง'  
print(v.replace('เด็กตาย','เด็กเต้น'))  # ได้ ไก่จิกเด็กเต้นเด็กเต้นบนปากโอ่ง

กรณีที่กำหนดจำนวนก็จะถูกแทนแค่จำนวนนั้น

print(v.replace('เด็กตาย','โดนเตียง',1))  # ได้ ไก่จิกโดนเตียงเด็กตายบนปากโอ่ง

กรณีที่อยากลบข้อความก็ทำได้โดยปล่อยว่าง

print(v.replace('จิกเด็กตายเด็ก',''))  # ได้ ไก่ตายบนปากโอ่ง

อ้างอิง

http://docs.python.jp/3/library/functions.html
http://python.civic-apps.com/string-find
http://python.civic-apps.com/string-split-join
http://www.isl.ne.jp/pcsp/python/python19.html

Reference : https://phyblas.hinaboshi.com/tsuchinoko11