Ruby :: Reversing a string by words or characters

Posted by PunNeng, Thu Feb 08 00:28:00 UTC 2007

คราวนี้ เราต้องการจะทำการเรียกย้อนกลับประโยค ทั้งในรูปแบบของคำและและตัวอักษร อันนี้ไม่ยาก เข้าใจง่าย โดยเราจะใช้ reverse method ในการ return ค่าที่เรียงเสร็จแล้ว แต่ string น้ันๆ ยังไม่เปลี่ียน แต่ถ้าต้องการให้ string นั้นๆ เปลี่ยนไปเลย ให้ใช้ reverse! method แทน

s = ".sdrawkcab si gnirts sihT"
s.reverse        # => "This string is backwards."
s                # => ".sdrawkcab si gnirts sihT"

s.reverse!       # => "This string is backwards."
s                # => "This string is backwards."

แต่ถ้าเราต้องการทำในรูปของคำล่ะ มาดูแบบนี้

s = "order. wrong the in are words These"
s.split(/(\s+)/).reverse!.join('')    # => "These words are in the wrong order."
s.split(/\b/).reverse!.join('')       # => "These words are in the wrong. order"

มาดูกัน String#split method จะรับ regular expression เข้ามาเพื่อทำการแยก string ออก แล้วค่อย return ออกมาเป็น array ของชุดที่ถูกแยกออกนั้น

ในส่วนของ regular expression ที่รับมาน้ัน คือ /(\s+)/ คือ เอาตัวที่เป็น white space ที่ติดกันมากกว่า 1 ตัวขึ้นไป ซึ่งหมายความว่าจะใช้ white space เป็นตัวแยก string ออกมา ซึ่ง white space นี จะต้องมีตั้งแต่ 1 ตัว หรือมากกว่าน้ันที่ติดๆ กัน ลองเข้า irb ดู แล้วพิมพ์ว่า

s = "order. wrong the in are words These"
s.split(/(s+)/)
# => ["order.", " ", "wrong", " ", "the", " ", "in", " ", "are", " ", "word", " ", "These"]

แต่ \b น้ัน หมายความว่า เอาที่เป็นขอบของคำ เพราะฉะน้ัน มันจะรวมพวกเครื่องหมายหรือสัญลักษณ์ต่างๆ มาด้วย ซึ่งหมายความว่า ใช้ขอบของคำ ซึ่งในที่นี้ ขอบของคำก็จะเป็นสิ่งที่อยู่ระหว่างคำ ซึ่งก็อาจจะรวมพวกเครื่องหมายต่างๆ เข้ามาด้วย ถ้ามันมี เป็นตัวแยก string ออกมา ลองพิมพ์ใน irb ต่อ จะได้

s.split(/\b/)
# => ["order", ". ", "wrong", " ", "the", " ", "in", " ", "are", " ", "word", " ", "These"]

พอได้แล้ว ก็เอามาทำการเรียงประโยคมาใหม่ แล้ว join กัน เอา array ที่ได้มา มา join กันให้เป็นประโยค แล้วทำไมต้อง join ด้วย '' ด้วย ก็เพราะว่าเรามี white space ในชุด array ของเราแล้ว

มีข้อสังเกตอยู่นิดนึง สำหรับ String#split ในกรณีนี้ ถ้าใน regular expression ของเราที่เราจะไว้เป็นตัวแยก อยู่ในวงเล็บ "()" เช่น /(\s*)/ อันนี้ มันจะรวมตัวแยกไปอยู่ใน array ด้วย ลองดูข้อแตกต่างของสองตัวอย่างนี้ครับ

"Three little  words".split(/\s+/)
# => ["Three", "little", "words"]
"Three little  words".split(/(\s+)/)
# => ["Three", " ", "little", "  ", "words"]

ปล. ผมเกลียด regular expression ไว้จะมาเจอกับมันเต็มๆ อีกที หึหึ

แก้ไขล่าสุด วันที่ 31 กรกฏาคม 2550 เวลา 1.12 น.

Filed Under: Ruby | Tags: howto ruby string

Comments

Have your say

A name is required. You may use HTML in your comments.




codegent: we're hiring