08 Ruby 字串物件
在 Ruby 中一切皆為物件,字串當然也不例外,本章中,您需要掌握字串物件的建立方法,通過常見字串例項方法的應用來掌握字串的例項方法。更重要的是,要理解字串也是一個物件。
1. 什麼是字串物件
Ruby 中的 String 物件持有並操縱一個或多個位元組的任意序列,通常表示代表人類語言的字元。——官方定義
一個或多個位元組的任意序列可以理解為我們所熟悉的語言文字,例如:“小明“、“123“、“abc“、或者特殊符號等。字串物件會顯示為我們為它賦予的文字。除此之外它可以對自身的文字內容進行擷取、部分刪除、插入文字等操作,比如我想在 “abcd” 的末尾增加一個 “e“,使這個字串變成 “abcde”。
那麼我們如何建立一個字串物件呢?
2. 字串物件建立的方法
建立字串物件的方法有很多種,最常用的建立方式是使用字串文字:單引號或雙引號之間的字元序列。兩種形式之間的區別是 Ruby 在構造文字時對字串進行的處理量。
2.1 單引號
定義:單引號記憶體放文字的字串物件。
除少數情況,單引號中的內容將成為字串的值。
使用場景:定義簡單的字串(不包含轉義符以及表示式插值操作)。
例項:
puts 'Hello Ruby!'
# ---- 輸出結果 ----
Hello Ruby!
當您想要在單引號字串中使用單引號'
時,為了不要讓 Ruby 將輸入的單引號理解為終止符號,您需要使用反斜槓\
。
例項:
# 輸出帶有'的單引號字串
puts 'What\'s your name?'
# ---- 輸出結果 ----
What's your name?
兩個連續的反斜槓\\
被單個反斜槓替換。
例項:
# 在單引號字串中輸入兩個反斜槓
puts 'escape using "\\"'
# ---- 輸出結果 ----
escape using "\"
2.2 雙引號
定義:雙引號記憶體放文字的字串物件。
使用場景:推薦用來定義複雜的字串(包括轉義符或者表示式插值操作)。
例項:
# 輸出一段文字
puts "Hello Ruby!"
# ---- 輸出結果 ----
Hello Ruby!
當使用雙引號建立字串物件時,首先他會查詢以反斜槓\
開頭的字元,進行轉義操作,其中最常見轉義符為\n
,它叫做換行符,當輸出包含換行符的字串的時候,\n
會被強制轉換為換行。
例項:
# 輸出帶有換行符的字串
puts "Goodnight,\nAlice"
# ---- 輸出結果 ----
Goodnight,
Alice
其次,雙引號字串做的第二件事是表示式插值,在字串中,#{表示式}
會被表示式的結果替換。
例項:
# 表示式插值
name = 'Alice' #定義一個區域性變數name,這裡的字串單引號雙引號均可
puts "Goodnight, #{name}"
# ---- 輸出結果 ----
Goodnight, Alice
表示式也可以是數學運算。
例項:
x, y, z = 12, 36, 72
puts "x 的值為 #{ x }"
puts "x + y 的值為 #{ x + y }"
puts "x + y + z 的平均值為 #{ (x + y + z)/3 }"
# ---- 輸出結果 ----
x 的值為 12
x + y 的值為 48
x + y + z 的平均值為 40
如果表示式只是全域性變數$
,類變數@@
或例項變數@
,則可以省略花括號。變數型別將在之後章節給大家普及。
例項:
puts "This is line #$."
# ---- 輸出結果 ----
This is line 1
經驗:除了#{}
這種表示式插值的形式,使用+
也可以進行字串拼接操作,但是要求進行拼接的兩個變數的型別一定是字串,否則會丟擲異常,Ruby 會將#{}
表示式中的結果強制轉化為字串,我們不需要關心變數的型別,只需要關心拼接的操作。所以,最好不使用+
來拼接字串。
對比下面兩種情況:
x = 12
puts "x 的值為 #{x}"
# ---- 輸出結果 ----
x 的值為 12
x = 12
puts "x 的值為 " + x
# ---- 輸出結果 ----
Traceback (most recent call last):
1: from ruby.rb:2:in `<main>'
ruby.rb:2:in `+': no implicit conversion of Integer into String (TypeError)
而這樣就不會丟擲異常:
x = 12
puts "x 的值為 " + x.to_s # 將12從數字轉化成字串
# ---- 輸出結果 ----
x 的值為 12
2.3 %q和%Q
定義:%q
同單引號規則,%Q
同雙引號規則。
使用場景:定義多行字串。
在q
和Q
之後的字元是分隔符,如果是[
、{
、(
、!
或<
則將讀取字串,直到找到匹配的結束符號,否則將一直讀取字元直到下一次出現相同的分隔符為止。
例項:
%q/生成單引號字元/ # 相當於 '生成單引號字元'
%Q!生成雙引號字元! # 相當於 "生成雙引號字元"
%Q{Seconds/day: #{24*60*60}} #相當於 "Seconds/day: #{24*60*60}"
# ---- 輸出結果 ----
生成單引號字元
生成雙引號字元
Seconds/day: 86400
2.4 Heredoc
定義:Heredoc 是定義多行字串,同時保持原始縮排和格式的一種方法。
使用場景:這用於嵌入諸如 SQL 或 HTML 之類的程式碼片段。
例項:
query = <<-SQL
SELECT * FROM food
WHERE healthy = true
SQL
# ---- 輸出結果 ----
"SELECT * FROM food\nWHERE healthy = true\n"
解釋:
您以符號<<-
開頭,然後是代表此 Heredoc 名稱的單詞,然後是 Heredoc 內容,然後在此文件的最後用該單詞關閉 Heredoc。
3. 字串例項方法應用
String 可能是最大的內建 Ruby 類,具有超過 75 種標準方法。我將在下面主要介紹最常用的例項方法。String類例項方法官方連結。
3.1 獲取字串長度
用來獲取字串中字元的個數。
例項:
"ruby".length
# 或者
"ruby".size
# ---- 輸出結果 ----
4
3.2 檢查一個字串是否為空
Tips:我們將空字串定義為長度為零的字串。
例項:
"".empty?
# 相當於
"".size == 0 # 但是empty?是更好的選擇
# ---- 輸出結果 ----
true
3.3 如何提取一個子字串
子字串(substring)是字串的一小部分,如果您只想要該特定部分的字串(例如開頭,中間或結尾),則很有用。
一種方法是使用方括號內的起始索引和多個字元,以逗號分隔:
例項:
string = "abc123" # 索引以0開始,代表第一個字元
# 從索引0開始擷取3個字元
string[0,3]
# 從索引3開始擷取3個字元
string[3,3]
# ---- 輸出結果 ----
"abc"
"123"
解釋:
-
第一個數字是起始索引;
-
第二個數字是您想要多少個字元。
您還可以使用範圍(range):
例項:
# 提取從第一個字元開始直到倒數第二個字元之間的字串
string = "abc123"
string[0..-2]
# ---- 輸出結果 ----
"abc12"
解釋:
-
第一個數字仍然是起始索引,但是第二個索引是結束索引(含端點);
-
-2
代表倒數第二個字元,而-1
是最後一個字元。
如果您想要刪除或替換子字串,您可以這樣做:
例項:
# 將從第一個字元開始直到第三個字元的字串設定成空字串
string = "abc123"
string[0..2] = ""
string
# ---- 輸出結果 ----
"123"
3.4 如何找出一個字串是否包含另一個字串
include?
方法:
Tips:在Ruby中,我們約定後面有一個
?
的方法返回值一定是true
或者false
。
例項:
# "Today is Saturday"裡面是否包含"Saturday"
string = "Today is Saturday"
string.include?("Saturday")
# ---- 輸出結果 ----
true
解釋:結果會返回true
或者false
index
方法:
例項:
string = "Today is Sunday"
string.index("day")
# ---- 輸出結果 ----
2
解釋:此方法會返回查詢的字串的第一個字元在被查詢字串中的索引。
Tips:如果結果是不包含,會返回
nil
3.5 判斷兩個字串是否相同(不區分大小寫)
Ruby 字串比較是要區分大小寫的,如果比較的兩個字串大小不同,則不相等。
對此我們常用的方法是使方程式的兩邊的字串都小寫或大寫。
例項:
# 將兩組字串都轉成大寫或者小寫
lang1 = "ruby"
lang2 = "Ruby"
puts lang1.upcase == lang2.upcase
puts lang1.downcase == lang2.downcase
# ---- 輸出結果 ----
true
true
Tips :
casecmp?
方法也可以做到這種事,使用較少,不推薦使用
3.6 如何刪除字串兩側多餘的空格
您可以使用strip
方法刪除多餘的空格:
例項:
# 刪除兩側多餘的空格
extra_space = " Hello World "
extra_space.strip
# ---- 輸出結果 ----
"Hello World"
經驗:當提交表單中包含姓名、郵箱、手機號這些引數的時候,經常會用到這個方法。
當您只想除去左側或者右側的多餘空格時,您可以使用lstrip
和 rstrip
。
例項:
extra_space = " Hello World "
p extra_space.lstrip # 刪除左側多餘的空格
p extra_space.rstrip # 刪除右側多餘的空格
# ---- 輸出結果 ----
"Hello World "
" Hello World"
3.7 字串的字首與字尾
檢視字串是否以特定字首開頭:
例項:
string = "ruby programming"
string.start_with? "ruby"
# ---- 輸出結果 ----
true
檢視字串是否以特定字尾結尾:
例項:
string = "ruby programming"
string.end_with? "programming"
# ---- 輸出結果 ----
true
刪除指定字首:
例項:
string = "ruby programming"
string.delete_prefix "ruby "
# ---- 輸出結果 ----
"programming"
刪除指定字尾:
例項:
string = "ruby programming"
string.delete_suffix " programming"
# ---- 輸出結果 ----
"ruby"
Tips :
delete_prefix
和delete_suffix
要在Ruby2.5
以上的版本才可以使用
3.8 將字串轉換為字元陣列
使用split
方法可以很容易地將字串分割成字元陣列:
例項:
string = "a b c d"
string.split
# ---- 輸出結果 ----
["a", "b", "c", "d"]
預設情況下,split
將使用空格作為分隔符,但是您可以將引數傳遞給此方法以指定其他分隔符。
例項:
# 將逗號作為分隔符
string = "a,b,c,d"
string.split(",")
# ---- 輸出結果 ----
["a", "b", "c", "d"]
3.9 將陣列轉換為字串
如果您想獲取一個字串陣列並將這些字串連線成一個大字串,則可以使用join
方法。
例項:
# 將由'a', 'b', 'c'字元組成的數組合併成一個字串
arr = ['a', 'b', 'c']
arr.join
# ---- 輸出結果 ----
"abc"
也可以通多傳遞引數指定字元分隔符。
例項:
arr = ['a', 'b', 'c']
arr.join("-")
# ---- 輸出結果 ----
"a-b-c"
3.10 將字串轉換為整數
如果要將"49"
之類的字串轉換為整數(Integer)的49
,可以使用to_i
方法。
例項:
"49".to_i
# ---- 輸出結果 ----
49
注意事項:如果您使用不包含數字的字串嘗試此操作,則將獲得0。
例項:
"a".to_i
# ---- 輸出結果 ----
0
3.11 檢查字串內容是否為一個整數
使用正則表示式(regular expression)來進行判斷:
例項:
"123".match?(/\A-?\d+\Z/)
"123bb".match?(/\A-?\d+\Z/)
# ---- 輸出結果 ----
true
false
Tips :
match?
是從ruby2.4以後才引入的,2.4之前的版本可以使用match
來代替。
解釋:上述正則表示式的意思為從字串的開頭(\A
)檢查是否有一個可選的負號(-?
,?
代表可選),然後確保中間有一些數字(\d+
)直到字串結尾(\Z
)沒有其它字元。
3.12 如何附加字元
您可以通過將字元附加到現有字串來從較小的字串構建較大的字串。這也稱為字串的串聯(string concatenation)
我們通過<<
方法來實現這個操作
例項:
string = ""
string << "hello"
string << " "
string << "there"
# ---- 輸出結果 ----
"hello there"
Tips:不要使用
+=
來進行字串連線,因為每次都會建立一個新字串,這對效能不利!
3.13 遍歷字串的字元
有時您需要對字串的每個字元進行操作,這個時候就需要遍歷字串的每個字元。
第一種方法,您可以使用each_char
方法:
例項:
# 輸出每一個字元
"rubyguides".each_char { |ch| puts ch # 這裡ch引數的名稱可以是任意的}
# ---- 輸出結果 ----
r
u
b
y
g
u
i
d
e
s
另外,您也可以使用chars
方法將字串轉換為字元陣列,對陣列上每個物件進行迭代(iterate)。
例項:
array_of_characters = "rubyguides".chars
# ---- 輸出結果 ----
["r", "u", "b", "y", "g", "u", "i", "d", "e", "s"]
3.14 字串轉換為大寫或小寫
如果要將字串所有字元全部大寫,可以使用upcase
方法:
例項:
"abcd".upcase
# ---- 輸出結果 ----
"ABCD"
如果要將字串所有字元全部小寫,可以使用downcase
方法。
例項:
"ABCD".downcase
# ---- 輸出結果 ----
"abcd"
3.15 建立多行字串
第一種方法,使用 Heredoc:
例項:
b = <<-STRING
aaa
bbb
ccc
STRING
# ---- 輸出結果 ----
"aaa\nbbb\nccc\n"
另一種,使用%Q
例項:
a = %Q(aaa
bbb
ccc
)
# ---- 輸出結果 ----
"aaa\nbbb\nccc\n"
3.16 使用gsub
替換字串中的文字
如果要替換字串中的文字,請使用gsub
方法:
例項:
# 讓我們用“cats”代替“dogs”一詞
string = "We have many dogs"
string.gsub("dogs", "cats")
# ---- 輸出結果 ----
"We have many cats"
如果要刪除字串,請使用空字串作為第二個引數。
例項:
string = "abccc"
string.gsub("c", "")
# ---- 輸出結果 ----
"ab"
注意事項:
-
gsub
方法返回一個新字串; -
如果要將更改應用於原始字串,可以使用
gsub!
方法。
gsub
方法還可以將正則表示式作為引數,因此您可以根據模式替換而不是確切的單詞。
例項:
string = "We have 3 cats"
string.gsub(/\d+/, "5")
# ---- 輸出結果 ----
"We have 5 cats"
解釋:這會將字串中的所有數字(\d+
)替換為數字5。
我們也可以和塊(block)一同使用
title = "the lord of the rings"
title.gsub(/\w+/) { |word| word.capitalize }
# ---- 輸出結果 ----
"The Lord Of The Rings"
Tips : 那麼
gsub
vssub
有什麼區別呢?
sub
和gsub
使用方法一樣,但是sub
只會替換第一個匹配項,gsub
會替換所有項。
3.17 從字串中刪除最後的\n
或\r
如果您要求使用者輸入某些內容(使用Kernel#gets
方法),則在字串末尾會有換行符(\n
),這將妨礙您直接比較字串。
刪除多餘的換行符(\n
)的最佳方法是使用chomp
方法。
例項:
puts "What's your name?"
name = gets
# 輸入名字Alice
# ---- 輸出結果 ----
"Alice\n"
使用chomp
方法後:
puts "What's your name?"
name = gets.chomp
# 輸入名字Alice
# ---- 輸出結果 ----
"Alice"
Tips :
chop
和chomp
的區別
chomp
只會刪除字串末尾的\n
或者\r
。
chop
會刪除字串末尾最後一個字元,不管是什麼字元。
從 Ruby 2.3 開始,chomp
方法採用一個可選引數,該引數允許您刪除要刪除的字元。
例項:
"abcd?".chomp("?")
# ---- 輸出結果 ----
"abcd"
如果傳入引數的字元不存在,它將返回原始字串。
3.18 如何更改字串編碼
字串按位元組序列儲存,根據它們的編碼,它們變成可以看到的字元。
例如,ASCII 編碼中的數字 65 表示字母“ A”。
但是,還有更復雜的編碼,例如 UTF-8,它允許您表示來自不同語言(中文等)甚至表情符號的字元。
要獲取字串的當前編碼,可以使用encoding
方法。
例項:
"abc".encoding
# ---- 輸出結果 ----
Encoding:UTF-8
從磁碟讀取檔案或從網站下載某些資料時,可能會遇到編碼問題。
您通常可以通過轉換編碼的方法force_encoding
來解決該問題。
例項:
"abc".force_encoding("UTF-8")
3.19 字元計數
您可以使用count
方法計算某一個字元在字串中出現的次數。
例項:
str = "aaab"
str.count("a")
# ---- 輸出結果 ----
3
str.count("b")
# ---- 輸出結果 ----
1
4. 小結
在本章中,您知道了什麼字串,瞭解如何建立一個字串物件,學習了字串常見的例項方法以及具體一些應用。
打好字串的基礎後,接下來讓我們繼續來學習下一章吧。