如何在 Ruby 中處理字符串

介紹

A string is a sequence of one or more characters that may consist of letters, numbers, or symbols.

Ruby中的字符串是物件,與其他語言不同,字符串是可變的,這意味著它們可以就地更改,而不是創建新的字符串。

您將在幾乎每個編寫的程序中使用字符串。字符串允許您使用文本顯示和與用戶通信。事實上,您現在正在閱讀的頁面是通過您的網絡瀏覽器在屏幕上顯示的字符串組成的。字符串是編程中最重要的基礎之一。

在本教程中,您將學習如何在Ruby中處理字符串。您將創建字符串,在屏幕上顯示它們,將它們存儲在變量中,將多個字符串連接在一起,並學習如何處理特殊字符,如換行符、撇號和雙引號。

創建和打印字符串

在Ruby中,字符串存在於單引號'或雙引號"之間,因此要創建字符串,請將一系列字符置於其中之一中:

'This is a string in single quotes.'

"This is a string in double quotes."

你可以選擇使用單引號或雙引號。在大多數情況下,選擇哪一種都沒有關係,只要你保持一致即可。但是,使用雙引號可以讓你執行字符串插值,你將在本教程中學到。

要在程序中顯示字符串,您可以使用print方法:

print "Let's print out this string."

print方法將字符串完全按照所寫的內容顯示。

試試吧。創建一個新的Ruby程序,名為print.rb,使用您的文本編輯器並使用print方法來打印三個字符串:

print.rb
print 'This is the first string.'
print 'This is the second string.'
print 'This is the third string.'

保存文件並運行程序:

  1. ruby print.rb

您將看到以下輸出:

Output
This is the first string.This is the second string.This is the third string.

不是將三個字符串分別打印在自己的行上,而是將所有三個字符串一起打印在一行上。 print方法將字符串打印到屏幕上,但如果您希望每個字符串都在自己的行上,則必須自己添加換行字符。

如果您希望所有三個字符串在不同的行上,請改用puts方法。將您的程序修改為使用puts而不是print

print.rb
puts 'This is the first string.'
puts 'This is the second string.'
puts 'This is the third string.'

現在再次運行程序,您將看到以下輸出:

Output
This is the first string. This is the second string. This is the third string.

puts方法打印您指定的字符串,但也為您在字符串末尾添加了一個換行字符。

將字串存儲在變數中

變數是對計算機內存中的一個位置的命名引用。您可以使用變數來存儲數據並稍後檢索它。

要將字符串存儲在變數中,請定義變數名並分配字符串的值:

my_string = 'This is my string'

然後,要檢索值,請使用變數的名稱:

print my_string

要自行測試此功能,請在編輯器中創建文件string_variables.rb並使用以下命令:

  1. nano string_variables.rb

然後添加以下代碼:

string_variables.rb
my_name = "Sammy the Shark"
my_age = "none of your business"

puts my_name
puts my_age

此程序定義了兩個變數:my_namemy_age。每個變數都分配了一個字符串。然後,我們使用puts方法將每個字符串分別打印出來。

使用CTRL + Xy保存文件,然後執行該程序:

  1. ruby string_variables.rb

您將看到以下輸出:

Output
Sammy the Shark none of your business

通過將字符串分配給變數,您可以避免每次想使用它時都重複輸入相同的字符串,這使得在程序中使用和操作字符串更加容易。

讓我們看看如何將字符串連接在一起以創建新的字符串。

字符串連接

串聯意味著將兩個或更多字符串連接在一起以創建新的字符串。為了串聯,我們使用串聯運算符,表示為一個+符號。當與算術操作一起使用時,+符號也是加法運算符。

這是如何將字符串sammyshark串聯在一起的:

"sammy" + "shark"

這將產生以下輸出:

Output
sammyshark

串聯將字符串端對端連接起來,將它們組合起來並輸出全新的字符串值。如果您希望單詞sammyshark之間有一個空格,則必須在其中一個字符串中包含該空格,如下所示:

"sammy " + "shark"

現在,您不會在程序中寫入此類代碼,但您經常需要將字符串和變量混合在一起,這就是串聯的用途。

這是一個例子:

color = "Blue"
print "My favorite color is " + color

這將產生輸出My favorite color is blue。請注意,在字符串中單詞is後留有一個空格,以便輸出中字符串和變量值之間有一個空格。

您可以以這種方式將多個字符串串聯在一起。創建文件concatenation.rb並添加此代碼:

concatenation.rb
my_name = "Sammy the Shark"
my_age = "none of your business"

puts "My name is " + my_name + " and my age is " + my_age + "."

此程序定義了兩個變量:my_namemy_age,每個變量都有其自己的分配字符串,就像您以前所做的一樣。但這一次,我們不是打印值,而是打印一個使用串聯打印這些值並添加了一些上下文的字符串。

當您運行此程序時,您將看到以下輸出:

Output
My name is Sammy the Shark and my age is none of your business.

在這個小程式中,您使用了串連來將變數插入這個字符串中。

當您通過串連結合兩個或更多的字符串時,您正在創建一個新的字符串,您可以在整個程序中使用,因此您可能希望將您創建的字符串分配給一個新的變數,稍後可以使用:

concatenation.rb
my_name = "Sammy the Shark"
my_age = "none of your business"

# 將串連的字符串分配給變量
output = "My name is " + my_name + " and my age is " + my_age + "."

# 輸出結果。
puts output

在這樣的小程式中,使用額外的 output 變量可能是不必要的。但在較大的程序中,您可能希望使用串連創建一個字符串,在多個地方使用它。將數據處理(如串連和算術)與輸出分開是一個好習慣,因為最終您的程序將變得更大,您將希望將邏輯和輸出分開到單獨的文件或組件中,以便更容易管理。

請務必不要在兩個不同的數據類型之間使用 + 運算符。例如,您不能將字符串和整數串連在一起。

為了查看發生了什麼,創建一個名為 strings_and_integers.rb 的新程序,內容如下:

strings_and_integers.rb
my_name = "Sammy the Shark"
my_number = 27

print my_name + my_number

這次我們有一個名為 my_name 的變量,其中包含字符串 Sammy the Shark,還有一個名為 my_number 的變量,其中包含整數 27。我們知道 27 不是一個字符串,因為它沒有被引號包圍。它也沒有小數點,所以我們知道它是一個整數。

如果您運行該程序:

  1. ruby strings_and_ints.rb

您將看到以下錯誤消息:

Output
strings_and_ints.rb:4:in `+': no implicit conversion of Integer into String (TypeError) from strings_and_ints.rb:4:in `<main>'

錯誤no implicit conversion of Integer into String 意味著 Ruby 只能將字符串連接到現有字符串中。

在 Ruby 版本 2.3 及以下版本中,你會看到這個錯誤信息:

strings_and_ints.rb:4:in `+': no implicit conversion of Fixnum into String (TypeError)
from strings_and_ints.rb:4:in `<main>'

在先前的 Ruby 版本中,數字被賦予了數據類型Fixnum。它是 Fixed Number 的縮寫。在 Ruby 2.4 中,Fixnum 和它的對應類型 Bignum 不再存在,取而代之的是 Integer

我們可以修改我們的程序,將數字27放在引號中 ("27"),這樣它就被聲明為字符串而不是整數。或者在創建字符串時將數字轉換為字符串,像這樣:

strings_and_integers.rb
my_name = "Sammy the Shark"
my_number = 27

print my_name + my_number.to_s

方法.to_s將整數轉換為字符串。這是一種更好的方法,因為它讓我們在程序中保持數字作為整數。我們只需要在打印出來時將其作為字符串,但如果需要在程序邏輯的其他部分使用它時,我們可能希望它作為整數存在。

再次運行程序,你會在屏幕上看到Sammy the Shark27被打印出來。

將數字轉換為字符串以進行連接是在處理郵政編碼、貨幣、電話號碼和其他數值數據時經常遇到的情況,你希望將其與文本一起顯示在屏幕上。

連接是強大的,但可能有些棘手。如果你不小心遺漏了一個+運算符,就會出現語法錯誤。如果你需要將字符串與保存數字的變量連接起來,你必須將變量轉換為字符串。Ruby提供了另一種將變量值注入字符串的方法,稱為字符串內插,它解決了這兩個問題。

使用字符串內插

當串聯字符串和變量時,輸出可能難以閱讀和調試。字符串內插通過讓你在雙引號中嵌入表達式來解決這個問題。

與其這樣寫:

"My name is " + my_name + "!"

你可以這樣做:

"My name is #{my_name}!"

不需要終止字符串並使用+運算符,而是用#{}語法將變量括起來。此語法告訴Ruby評估表達式並將其注入字符串中。

試試看。創建一個名為interpolation.rb的新程序,並添加以下代碼:

interpolation.rb
my_name = "Sammy the Shark"
my_age = "none of your business"

output = "My name is #{my_name} and my age is #{my_age}."

puts output

這是你已經寫過的同一個程序,但這次我們使用字符串內插來創建輸出。

字符串內插還有另一個好處:它可以自動將數值轉換為字符串。還記得你的strings_and_integers.rb程序嗎?再次在編輯器中打開該文件,但將最後一行更改為如下所示:

strings_and_integers.rb
my_name = "Sammy the Shark"
my_number = 27

# 使用插值而不是串接
print "My name is #{my_name} and my favorite number is #{my_number}."

當你運行它時,Ruby會自動將my_number轉換為字符串,並且您的程序將打印以下輸出:

Output
My name is Sammy the Shark and my favorite number is 27.

字符串插值是強大而方便的。這也是串接帶變量的字符串的首選方法。

字符串字面量和字符串值

請注意,您創建的所有字符串都在代碼中用引號括起來,但實際打印的輸出不包括引號。

在引用它們時有一個區別。字符串字面量是源代碼中的字符串,包括引號。字符串值是您在輸出中看到的,不包括引號。

這是一個字符串字面量:

"Sammy the Shark"

字符串值將是Sammy the Shark

在大多數情況下,您不必擔心這種差異,除非您想在字符串中使用引號或撇號等特殊字符。

在字符串中轉義引號和撇號

由於引號用於表示字符串,如果你想在字符串中使用撇號和引號,你需要做一些額外的工作。

如果你嘗試在單引號字符串中間使用撇號,像這樣:

'This isn't what I wanted.'

isn't中的撇號結束了字符串,正如你可以從這個示例的奇怪高亮顯示的那樣。因此,Ruby解釋器將嘗試解析其餘部分的字符串作為代碼,並且你將得到一個錯誤。

如果你在一個由雙引號括起來的字符串中使用雙引號,你會遇到同樣的情況:

"Sammy says, "Hello!""

在這個示例中,位於Hello前面的結束雙引號終止了字符串,而位於Hello!後面的雙引號創建了一個新的字符串,它沒有匹配的雙引號來終止它,所以Ruby會顯示一個錯誤。

為了避免這個問題,你有幾個選擇。首先,你可以使用替代的字符串語法;如果你必須在字符串中使用雙引號,使用單引號定義字符串,反之亦然。你也可以轉義引號,或者你可以使用不同的Ruby語法來定義字符串。讓我們來看看每種方法。

選項1:使用替代字符串語法

最簡單的解決方法是在字符串需要包含雙引號時,將字符串括在單引號中,並在字符串需要使用單引號時,將字符串括在雙引號中。

而不是使用單引號定義此字符串:

'This isn't what I wanted.'

使用雙引號定義它:

"This isn't what I wanted."

而不是使用雙引號定義此字符串:

"Sammy says, "Hello!""

使用單引號:

'Sammy says, "Hello!"'

使用替代語法可以幫助您應對一些快速問題,但這並不總是有效。例如,這兩種方法都無法處理此字符串:

"Sammy says, "I'm a happy shark!""

在這個例子中,I'm前面的結尾雙引號使事情變得混亂。這終止了第一個字符串,然後Ruby遇到I'm中的撇號,這開始了一個新字符串,其值為m a happy shark!""。但這個新字符串沒有匹配的單引號來終止它。使用單引號括住字符串引入了類似的問題:

'Sammy says, "I'm a happy shark!"'

這次I'm中的撇號終止了字符串。

使用替代語法還可能使您的代碼不一致。不斷在字符串語法之間切換可能會讓人感到困惑,我們可以轉義字符來解決這個問題。

選項2:在字符串中轉義字符

反斜線字符(\),常被稱為字符串中的轉義字符,將阻止 Ruby 直接解釋字符串中的下一個字符。

這是我們有問題的字符串,用雙引號編碼,其中包含雙引號:

"Sammy says, "I'm a happy shark!""

創建一個名為quoting.rb的新 Ruby 程序並將此代碼添加到文件中:

quoting.rb
print "Sammy says, "I'm a happy shark!""

運行程序:

  1. ruby quoting.rb

然後您會看到這個輸出:

Output
quoting.rb:1: syntax error, unexpected tCONSTANT, expecting end-of-input print "Sammy says, "I'm a happy shark!"" ^

為了修復錯誤,在內部雙引號前面使用反斜線:

quoting.rb
print "Sammy says, \"I'm a happy shark!\""

然後再次運行程序,您將看到預期的輸出:

Sammy says, "I'm a happy shark!"

請注意,在這個例子中您不必轉義撇號,因為沒有衝突。您只需要轉義會混淆 Ruby 的引號。

您可以通過使用不同的語法來定義字符串,從而完全避免轉義引號。

選項 3:使用字符串的替代語法

到目前為止,您已經使用引號來定義字符串的邊界。您還可以使用其他字符來創建 Ruby 中的字符串。您可以通過在百分比符號後指定它來定義定界符或您想用來封閉字符串的字符,就像這樣:

%$Sammy says, "I'm a happy shark!"$

此語法將自動為您轉義嵌入的字符串。實際字符串看起來像這樣:

"Sammy says, \"I'm a happy shark!\""

然而,更改定界符意味着您必须在需要使用它时转义定界符。在这种情况下,如果您必须在字符串中使用美元符号,您需要转义字符串中的字面美元符号。

为了避免这种情况,您还可以使用花括号、方括号或圆括号作为定界符。花括号是最常见的:

%{Sammy says, "I'm a happy shark!"}

这些形式都支持字符串插值,如果需要的话。

droplets = 5
print %{Sammy says, "I just created #{droplets} droplets!"}

您还会看到在Ruby程序中使用%Q{}%q{}来定义字符串。%Q{}语法与双引号字符串的工作方式完全相同,这意味着您不必转义双引号,并且可以使用字符串插值:

droplets = 5
print %Q{Sammy says, "I just created #{droplets} droplets!"}

%q{}语法与单引号字符串的工作方式完全相同:

%q{Sammy says, "I'm a happy shark!"}

您可能会在某些程序中看到%q%Q语法与圆括号或方括号一起使用,而不是花括号。

正如您所看到的,有很多在Ruby中创建字符串的方式。无论您选择哪种方法,在您的代码中保持一致。您会发现%Q{}%{}方法最常用。

现在您知道如何处理特殊字符了,让我们看看如何处理长字符串和换行字符。

长字符串和换行符

有時候,您可能想在字符串中插入換行符或回車符。 您可以使用\n\r逸出字符來在代碼中插入換行:

output = "This is\na string\nwith newlines"
puts output

該程序將生成以下輸出:

Output
This is a string with newlines

從技術上講,這樣可以使我們的輸出跨越多行。 但是,在單行上寫一個非常長的字符串將很快變得難以閱讀和處理。 有幾個解決方案。

首先,您可以使用串聯運算符將字符串拆分為多行:

output = "This is a\n" +
"longer string\n" +
"with newlines."
puts output

這只是將三個字符串連接在一起,類似於您已經做過的操作。

您還可以直接將斷行符放在字符串中:

output = "This is a
longer string
with newlines"
puts output

您還可以使用任何替代字符串語法來創建多行字符串:

output = %{This is a
longer string
with newlines}
puts output

在這兩個示例中,請注意我們不需要換行符(\n)字符。 這種方法保留了空格,包括縮進和換行符。

因此,輸出將包含換行符以及所有前導縮進,如下所示:

Output
This is a longer string with newlines

為了防止這種情況,從代碼中刪除額外的空格:

output = %{This is a
longer string
with newlines
}

您還可以使用heredoc或“此處文件”來創建多行字符串,這是程序中用於多行字符串字面值的術語。 下面是您將編寫該代碼的方式:

output = <<-END
This is a
longer string
with newlines
END

<<-ENDEND標記表示此處文件的開始和結束。

在Ruby中,Heredocs 也保留空白字符,這意味著如果你在 heredoc 中縮排代碼,前導縮排也會被保留。因此,這段代碼:

output = <<-END
This is a
longer string
with newlines
END

會打印出兩個空格的縮排。

Ruby 2.3 及更高版本提供了“squiggly heredoc” 語法,它會自動刪除這個前導空白。將 heredoc 定義中的連字符替換為波浪符號,所以 <<- 變為 <<~,就像這樣:

output = <<~END
This is a
longer string
with newlines
and the code is indented
but the output is not.
END

這將產生以下輸出:

Output
This is a longer string with newlines and the code is indented but the output is not.

這讓你可以使用 heredocs 並保持代碼良好的縮排。

Ruby 中的 Heredocs 也支持字符串插值。

正如你所見,Ruby 中有很多處理換行和多行字符串的方法。當你處理現有的 Ruby 代碼時,你會遇到所有這些方法,因為每個項目往往都有自己的風格。在你自己的代碼中,選擇適合你的風格並保持一致。

字符串重複

有時你需要使用 Ruby 重複多次一個字符串。你可以使用 * 運算符來實現這一點。像 + 運算符一樣,當與數字一起使用時,* 運算符有不同的用法,它是乘法的運算符。當與一個字符串和一個整數一起使用時,*字符串重複運算符,使用你提供的整數重複一個字符串。

Sammy打印九次,您將使用以下代碼:

print "Sammy" * 9

此代碼生成以下輸出:

Output
SammySammySammySammySammySammySammySammySammy

您可以使用這個方法創建一些漂亮的ASCII藝術。創建一個名為banner.rb的文件,並添加以下代碼:

puts "=" * 15
puts "| Hello World |"
puts "=" * 15

在運行之前,您能想像程序將生成什麼嗎?

它生成這個輸出:

Output
=============== | Hello World | ===============

這只是如何讓計算機為您執行重複任務的一個小例子。

結論

在本教程中,您學到了如何在Ruby編程語言中處理字符串數據類型。您創建了新字符串,將它們與其他字符串串聯在一起,並處理了換行符、引號和撇號。然後,您使用字符串插值使混合字符串和變量值更容易,並學會了如何重複字符串。

Source:
https://www.digitalocean.com/community/tutorials/how-to-work-with-strings-in-ruby