1. 程式人生 > Ruby 程式語言入門 >08 Ruby 字串物件

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同雙引號規則。

使用場景:定義多行字串。

qQ之後的字元是分隔符,如果是[{(!<則將讀取字串,直到找到匹配的結束符號,否則將一直讀取字元直到下一次出現相同的分隔符為止。

例項:

%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"

解釋:

  1. 第一個數字是起始索引;

  2. 第二個數字是您想要多少個字元。

您還可以使用範圍range):

例項:

# 提取從第一個字元開始直到倒數第二個字元之間的字串
string = "abc123"
string[0..-2]

# ---- 輸出結果 ----
"abc12"

解釋:

  1. 第一個數字仍然是起始索引,但是第二個索引是結束索引(含端點);

  2. -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"

經驗:當提交表單中包含姓名、郵箱、手機號這些引數的時候,經常會用到這個方法。

當您只想除去左側或者右側的多餘空格時,您可以使用lstriprstrip

例項:

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_prefixdelete_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"

注意事項:

  1. gsub方法返回一個新字串;

  2. 如果要將更改應用於原始字串,可以使用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 vs sub有什麼區別呢?

subgsub使用方法一樣,但是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"

Tipschopchomp的區別

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. 小結

在本章中,您知道了什麼字串,瞭解如何建立一個字串物件,學習了字串常見的例項方法以及具體一些應用。

打好字串的基礎後,接下來讓我們繼續來學習下一章吧。