就像 Ruby 裡的所有東西一樣,String 也是物件。
字串由任意位元組序列(通常是字元)組成,並且像其他物件一樣被初始化與操作。
事實上,Ruby 最實用的地方之一,就是有大量方法可以呼叫在字串(以及其他物件)上,讓你省下許多寫程式的時間。
在這個練習中,我們要來探索並玩玩其中一些輔助方法。
雖然你可以用 String.new(...) 建立字串,但更常見的做法是使用字面值。
你可以使用的字面值有很多種,它們分成兩類:允許內插的和不允許內插的。
最常見的字面值是單引號和雙引號('...' 和 "...")。
單引號不允許內插,而雙引號可以。
內插是指用 #{} 語法把一個字串放進另一個字串裡。
# Use single quotes when not interpolated
location = 'World'
# And double quotes when interpolated
puts "Hello, #{location}!" #=> "Hello, World!"
你也可以使用其他的字面值,例如用 %{... } 表示內插字串,用 %q{...} 表示非內插字串。
如果你的字串裡含有 ' 或 " 這些字元,這些寫法就很有用。
注意:並沒有絕對的規則說,如果你的字串不含內插,就一定得用非內插字串。
把 Ruby 裡的字串想成和陣列很類似,會很有幫助。
它們有大小,而且字元都有索引(第一個索引是 0):
my_string = "Some string"
my_string.size #=> 11
my_string[0] #=> 'S'
my_string[1] #=> 'o'
my_string[-1] #=> 'g'
# Find the first index of a character
my_string.index('m') #=> 2
你可以用索引或 slice 取出字串的某一部分:
my_string = "Some string"
# Find three characters starting with the second character (index 1)
my_string[1, 3] #=> "ome"
my_string.slice(1, 3) #=> "ome"
字串的實際內容也可以操作。 值得去看看 Ruby 文件 了解所有方法,不過這裡先舉幾個常用的例子:
"hello".capitalize #=> "Hello"
"HELLO".downcase #=> "hello"
"hello".center(9) #=> " hello "
" hello ".strip #=> "hello"
"hello world".split(" ") #=> ["hello", "world"]
你也可以用 gsub 這類方法來替換字元:
# Replace one character with another
"noob".gsub("o","0") #=> "n00b"
# (Advanced) Replace a regular expression
"Ruby really rocks".gsub(/[aieou]/,'') #=> "Rby rlly rcks"
上面所有的例子都會回傳一個新的 String。
不過,許多方法都有以 ! 結尾的對應版本,會直接修改字串本身。
# Use normal methods to return new strings
my_string = "hello"
my_string.capitalize #=> "Hello"
puts my_string #=> "hello"
# And bang-methods (...!) to modify the object
my_string = "hello"
my_string.capitalize! #=> "Hello"
puts my_string #=> "Hello"
在這道練習中,你會處理日誌行。
每一行日誌都是一個格式如下的字串:"[<LEVEL>]: <MESSAGE>"。
一共有三種不同的日誌等級:
INFOWARNINGERROR你有三個任務,每個任務都會取用一行日誌,並要求你對它做點處理。 解決這些任務的方法有很多種,你可以從上面的範例中挑選自己喜歡的幾種,然後看看能想出什麼吧!
實作 LogLineParser#message 方法,回傳日誌行的訊息:
LogLineParser.new('[ERROR]: Invalid operation').message
# => "Invalid operation"
開頭或結尾的空白都應該被移除:
LogLineParser.new("[WARNING]: Disk almost full\r\n").message
# => "Disk almost full"
實作 LogLineParser#log_level 方法,回傳日誌行的日誌等級,而且要以小寫回傳:
LogLineParser.new('[ERROR]: Invalid operation').log_level
# => "error"
實作 LogLineParser#reformat 方法,重新格式化日誌行,把訊息放在前面,並將日誌等級接在後面、用括號括起來:
LogLineParser.new('[INFO]: Operation completed').reformat
# => "Operation completed (info)"