Ruby 字串(String)

Ruby 字串(String)

Ruby 中的 String 物件用於儲存或操作一個或多個位元組的序列。

Ruby 字串分為單引號字串(')和雙引號字串("),區別在於雙引號字串能夠支援更多的轉義字元。

單引號字串

最簡單的字串是單引號字串,即在單引號記憶體放字串:

'這是一個 Ruby 程式的字串'

如果您需要在單引號字串內使用單引號字元,那麼需要在單引號字串使用反斜槓(\),這樣 Ruby 直譯器就不會認為這個單引號字元是字串的終止符號:

'Won\'t you read O\'Reilly\'s book?'

反斜槓也能轉義另一個反斜槓,這樣第二個反斜槓本身不會解釋為轉義字元。

以下是 Ruby 中字串相關的特性。

雙引號字串

在雙引號字串中我們可以使用 #{} 井號和大括號來計算表示式的值:

字串中嵌入變數:

例項

#!/usr/bin/ruby # -*- coding: UTF-8 -*- name1 = "Joe" name2 = "Mary" puts "你好 #{name1}, #{name2} 在哪?"

嘗試一下 ?

以上例項輸出執行輸出結果為:

你好 Joe,  Mary 在哪?

字串中進行數學運算:

例項

#!/usr/bin/ruby # -*- coding: UTF-8 -*- 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

Ruby 中還支援一種採用 %q 和 %Q 來引導的字串變數,%q 使用的是單引號引用規則,而 %Q 是雙引號引用規則,後面再接一個 (! [ { 等等的開始界定符和與 } ] ) 等等的末尾界定符。

跟在 q 或 Q 後面的字元是分界符.分界符可以是任意一個非字母數字的單位元組字元.如:[,{,(,<,!等,字串會一直讀取到發現相匹配的結束符為止.

例項

#!/usr/bin/ruby # -*- coding: UTF-8 -*- desc1 = %Q{Ruby 的字串可以使用 '' 和 ""。} desc2 = %q|Ruby 的字串可以使用 '' 和 ""。| puts desc1 puts desc2

嘗試一下 ?

以上例項輸出執行輸出結果為:

Ruby 的字串可以使用 '' 和 ""。
Ruby 的字串可以使用 '' 和 ""。

轉義字元

下標列出了可使用反斜槓符號轉義的轉義字元或非列印字元。

注意:在一個雙引號括起的字串內,轉義字元會被解析。在一個單引號括起的字串內,轉義字元不會被解析,原樣輸出。

反斜槓符號十六進位制字元描述
\a0x07報警符
\b0x08退格鍵
\cx Control-x
\C-x Control-x
\e0x1b轉義符
\f0x0c換頁符
\M-\C-x Meta-Control-x
\n0x0a換行符
\nnn 八進位制表示法,其中 n 的範圍為 0.7
\r0x0d回車符
\s0x20空格符
\t0x09製表符
\v0x0b垂直製表符
\x 字元 x
\xnn 十六進位制表示法,其中 n 的範圍為 0.9、 a.f 或 A.F

字元編碼

Ruby 的預設字符集是 ASCII,字元可用單個位元組表示。如果您使用 UTF-8 或其他現代的字符集,字元可能是用一個到四個位元組表示。

您可以在程式開頭使用 $KCODE 改變字符集,如下所示:

$KCODE = 'u'

下面是 $KCODE 可能的值。

編碼描述
aASCII (與 none 相同)。這是預設的。
eEUC。
nNone (與 ASCII 相同)。
uUTF-8。

字串內建方法

我們需要有一個 String 物件的例項來呼叫 String 方法。下面是建立 String 物件例項的方式:

new [String.new(str="")]

這將返回一個包含 str 副本的新的字串物件。現在,使用 str 物件,我們可以呼叫任意可用的例項方法。例如:

例項

#!/usr/bin/ruby myStr = String.new("THIS IS TEST") foo = myStr.downcase puts "#{foo}"

這將產生以下結果:

this is test

下面是公共的字串方法(假設 str 是一個 String 物件):

序號方法 & 描述
1str % arg
使用格式規範格式化字串。如果 arg 包含一個以上的替代,那麼 arg 必須是一個數組。如需瞭解更多格式規範的資訊,請檢視"核心模組"下的 sprintf。
2str * integer
返回一個包含 integer 個 str 的新的字串。換句話說,str 被重複了 integer 次。
3str + other_str
連線 other_str 到 str。
4str << obj
連線一個物件到字串。如果物件是範圍為 0.255 之間的固定數字 Fixnum,則它會被轉換為一個字元。把它與 concat 進行比較。
5str <=> other_str
把 str 與 other_str 進行比較,返回 -1(小於)、0(等於)或 1(大於)。比較是區分大小寫的。
6str == obj
檢查 str 和 obj 的相等性。如果 obj 不是字串,則返回 false,如果 str <=> obj,則返回 true,返回 0。
7str =~ obj
根據正則表示式模式 obj 匹配 str。返回匹配開始的位置,否則返回 false。
8str[position] # 注意返回的是ASCII碼而不是字元
str[start, length]
str[start..end]
str[start...end]

使用索引擷取子串
9str.capitalize
把字串轉換為大寫字母顯示。
10str.capitalize!
與 capitalize 相同,但是 str 會發生變化並返回。
11str.casecmp
不區分大小寫的字串比較。
12str.center
居中字串。
13str.chomp
從字串末尾移除記錄分隔符($/),通常是 \n。如果沒有記錄分隔符,則不進行任何操作。
14str.chomp!
與 chomp 相同,但是 str 會發生變化並返回。
15str.chop
移除 str 中的最後一個字元。
16str.chop!
與 chop 相同,但是 str 會發生變化並返回。
17str.concat(other_str)
連線 other_str 到 str。
18str.count(str, ...)
給一個或多個字符集計數。如果有多個字符集,則給這些集合的交集計數。
19str.crypt(other_str)
對 str 應用單向加密雜湊。引數是兩個字元長的字串,每個字元的範圍為 a.z、 A.Z、 0.9、 . 或 /。
20str.delete(other_str, ...)
返回 str 的副本,引數交集中的所有字元會被刪除。
21str.delete!(other_str, ...)
與 delete 相同,但是 str 會發生變化並返回。
22str.downcase
返回 str 的副本,所有的大寫字母會被替換為小寫字母。
23str.downcase!
與 downcase 相同,但是 str 會發生變化並返回。
24str.dump
返回 str 的版本,所有的非列印字元被替換為 \nnn 符號,所有的特殊字元被轉義。
25str.each(separator=$/) { |substr| block }
使用引數作為記錄分隔符(預設是 $/)分隔 str,傳遞每個子字串給被提供的塊。
26str.each_byte { |fixnum| block }
傳遞 str 的每個位元組給 block,以位元組的十進位制表示法返回每個位元組。
27str.each_line(separator=$/) { |substr| block }
使用引數作為記錄分隔符(預設是 $/)分隔 str,傳遞每個子字串給被提供的 block。
28str.empty?
如果 str 為空(即長度為 0),則返回 true。
29str.eql?(other)
如果兩個字串有相同的長度和內容,則這兩個字串相等。
30str.gsub(pattern, replacement) [or]
str.gsub(pattern) { |match| block }

返回 str 的副本,pattern 的所有出現都替換為 replacement 或 block 的值。pattern 通常是一個正則表示式 Regexp;如果是一個字串 String,則沒有正則表示式元字元被解釋(即,/\d/ 將匹配一個數字,但 '\d' 將匹配一個反斜槓後跟一個 'd')。
31str[fixnum] [or] str[fixnum,fixnum] [or] str[range] [or] str[regexp] [or] str[regexp, fixnum] [or] str[other_str]
使用下列的引數引用 str:引數為一個 Fixnum,則返回 fixnum 的字元編碼;引數為兩個 Fixnum,則返回一個從偏移(第一個 fixnum)開始截至到長度(第二個 fixnum)為止的子字串;引數為 range,則返回該範圍內的一個子字串;引數為 regexp,則返回匹配字串的部分;引數為帶有 fixnum 的 regexp,則返回 fixnum 位置的匹配資料;引數為 other_str,則返回匹配 other_str 的子字串。一個負數的 Fixnum 從字串的末尾 -1 開始。
32str[fixnum] = fixnum [or] str[fixnum] = new_str [or] str[fixnum, fixnum] = new_str [or] str[range] = aString [or] str[regexp] =new_str [or] str[regexp, fixnum] =new_str [or] str[other_str] = new_str ]
替換整個字串或部分字串。與 slice! 同義。
33str.gsub!(pattern, replacement) [or] str.gsub!(pattern) { |match| block }
執行 String#gsub 的替換,返回 str,如果沒有替換被執行則返回 nil。
34str.hash
返回一個基於字串長度和內容的雜湊。
35str.hex
把 str 的前導字元當作十六進位制數字的字串(一個可選的符號和一個可選的 0x),並返回相對應的數字。如果錯誤則返回零。
36str.include? other_str [or] str.include? fixnum
如果 str 包含給定的字串或字元,則返回 true。
37str.index(substring [, offset]) [or]
str.index(fixnum [, offset]) [or]
str.index(regexp [, offset])

返回給定子字串、字元(fixnum)或模式(regexp)在 str 中第一次出現的索引。如果未找到則返回 nil。如果提供了第二個引數,則指定在字串中開始搜尋的位置。
38str.insert(index, other_str)
在給定索引的字元前插入 other_str,修改 str。負值索引從字串的末尾開始計數,並在給定字元後插入。其意圖是在給定的索引處開始插入一個字串。
39str.inspect
返回 str 的可列印版本,帶有轉義的特殊字元。
40str.intern [or] str.to_sym
返回與 str 相對應的符號,如果之前不存在,則建立符號。
41str.length
返回 str 的長度。把它與 size 進行比較。
42str.ljust(integer, padstr=' ')
如果 integer 大於 str 的長度,則返回長度為 integer 的新字串,新字串以 str 左對齊,並以 padstr 作為填充。否則,返回 str。
43str.lstrip
返回 str 的副本,移除了前導的空格。
44str.lstrip!
從 str 中移除前導的空格,如果沒有變化則返回 nil。
45str.match(pattern)
如果 pattern 不是正則表示式,則把 pattern 轉換為正則表示式 Regexp,然後在 str 上呼叫它的匹配方法。
46str.oct
把 str 的前導字元當作十進位制數字的字串(一個可選的符號),並返回相對應的數字。如果轉換失敗,則返回 0。
47str.replace(other_str)
把 str 中的內容替換為 other_str 中的相對應的值。
48str.reverse
返回一個新字串,新字串是 str 的倒序。
49str.reverse!
逆轉 str,str 會發生變化並返回。
50str.rindex(substring [, fixnum]) [or]
str.rindex(fixnum [, fixnum]) [or]
str.rindex(regexp [, fixnum])

返回給定子字串、字元(fixnum)或模式(regexp)在 str 中最後一次出現的索引。如果未找到則返回 nil。如果提供了第二個引數,則指定在字串中結束搜尋的位置。超出該點的字元將不被考慮。
51str.rjust(integer, padstr=' ')
如果 integer 大於 str 的長度,則返回長度為 integer 的新字串,新字串以 str 右對齊,並以 padstr 作為填充。否則,返回 str。
52str.rstrip
返回 str 的副本,移除了尾隨的空格。
53str.rstrip!
從 str 中移除尾隨的空格,如果沒有變化則返回 nil。
54str.scan(pattern) [or]
str.scan(pattern) { |match, ...| block }

兩種形式匹配 pattern(可以是一個正則表示式 Regexp 或一個字串 String)遍歷 str。針對每個匹配,會生成一個結果,結果會新增到結果陣列中或傳遞給 block。如果 pattern 不包含分組,則每個獨立的結果由匹配的字串、$& 組成。如果 pattern 包含分組,每個獨立的結果是一個包含每個分組入口的陣列。
55str.slice(fixnum) [or] str.slice(fixnum, fixnum) [or]
str.slice(range) [or] str.slice(regexp) [or]
str.slice(regexp, fixnum) [or] str.slice(other_str)
See str[fixnum], etc.
str.slice!(fixnum) [or] str.slice!(fixnum, fixnum) [or] str.slice!(range) [or] str.slice!(regexp) [or] str.slice!(other_str)

從 str 中刪除指定的部分,並返回刪除的部分。如果值超出範圍,引數帶有 Fixnum 的形式,將生成一個 IndexError。引數為 range 的形式,將生成一個 RangeError,引數為 Regexp 和 String 的形式,將忽略執行動作。
56str.split(pattern=$;, [limit])

基於分隔符,把 str 分成子字串,並返回這些子字串的陣列。

如果 pattern 是一個字串 String,那麼在分割 str 時,它將作為分隔符使用。如果 pattern 是一個單一的空格,那麼 str 是基於空格進行分割,會忽略前導空格和連續空格字元。

如果 pattern 是一個正則表示式 Regexp,則 str 在 pattern 匹配的地方被分割。當 pattern 匹配一個零長度的字串時,str 被分割成單個字元。

如果省略了 pattern 引數,則使用 $; 的值。如果 $; 為 nil(預設的),str 基於空格進行分割,就像是指定了 ` ` 作為分隔符一樣。

如果省略了 limit 引數,會抑制尾隨的 null 欄位。如果 limit 是一個正數,則最多返回該數量的欄位(如果 limit 為 1,則返回整個字串作為陣列中的唯一入口)。如果 limit 是一個負數,則返回的欄位數量不限制,且不抑制尾隨的 null 欄位。

57str.squeeze([other_str]*)
使用為 String#count 描述的程式從 other_str 引數建立一系列字元。返回一個新的字串,其中集合中出現的相同的字元會被替換為單個字元。如果沒有給出引數,則所有相同的字元都被替換為單個字元。
58str.squeeze!([other_str]*)
與 squeeze 相同,但是 str 會發生變化並返回,如果沒有變化則返回 nil。
59str.strip
返回 str 的副本,移除了前導的空格和尾隨的空格。
60str.strip!
從 str 中移除前導的空格和尾隨的空格,如果沒有變化則返回 nil。
61str.sub(pattern, replacement) [or]
str.sub(pattern) { |match| block }

返回 str 的副本,pattern 的第一次出現會被替換為 replacement 或 block 的值。pattern 通常是一個正則表示式 Regexp;如果是一個字串 String,則沒有正則表示式元字元被解釋。
62str.sub!(pattern, replacement) [or]
str.sub!(pattern) { |match| block }

執行 String#sub 替換,並返回 str,如果沒有替換執行,則返回 nil。
63str.succ [or] str.next
返回 str 的繼承。
64str.succ! [or] str.next!
相當於 String#succ,但是 str 會發生變化並返回。
65str.sum(n=16)
返回 str 中字元的 n-bit 校驗和,其中 n 是可選的 Fixnum 引數,預設為 16。結果是簡單地把 str 中每個字元的二進位制值的總和,以 2n - 1 為模。這不是一個特別好的校驗和。
66str.swapcase
返回 str 的副本,所有的大寫字母轉換為小寫字母,所有的小寫字母轉換為大寫字母。
67str.swapcase!
相當於 String#swapcase,但是 str 會發生變化並返回,如果沒有變化則返回 nil。
68str.to_f
返回把 str 中的前導字元解釋為浮點數的結果。超出有效數字的末尾的多餘字元會被忽略。如果在 str 的開頭沒有有效數字,則返回 0.0。該方法不會生成異常。
69str.to_i(base=10)
返回把 str 中的前導字元解釋為整數基數(基數為 2、 8、 10 或 16)的結果。超出有效數字的末尾的多餘字元會被忽略。如果在 str 的開頭沒有有效數字,則返回 0。該方法不會生成異常。
70str.to_s [or] str.to_str
返回接收的值。
71str.tr(from_str, to_str)
返回 str 的副本,把 from_str 中的字元替換為 to_str 中相對應的字元。如果 to_str 比 from_str 短,那麼它會以最後一個字元進行填充。兩個字串都可以使用 c1.c2 符號表示字元的範圍。如果 from_str 以 ^ 開頭,則表示除了所列出的字元以外的所有字元。
72str.tr!(from_str, to_str)
相當於 String#tr,但是 str 會發生變化並返回,如果沒有變化則返回 nil。
73str.tr_s(from_str, to_str)
把 str 按照 String#tr 描述的規則進行處理,然後移除會影響翻譯的重複字元。
74str.tr_s!(from_str, to_str)
相當於 String#tr_s,但是 str 會發生變化並返回,如果沒有變化則返回 nil。
75str.unpack(format)
根據 format 字串解碼 str(可能包含二進位制資料),返回被提取的每個值的陣列。format 字元由一系列單字元指令組成。每個指令後可以跟著一個數字,表示重複該指令的次數。星號(*)將使用所有剩餘的元素。指令 sSiIlL 每個後可能都跟著一個下劃線(_),為指定型別使用底層平臺的本地尺寸大小,否則使用獨立於平臺的一致的尺寸大小。format 字串中的空格會被忽略。
76str.upcase
返回 str 的副本,所有的小寫字母會被替換為大寫字母。操作是環境不敏感的,只有字元 a 到 z 會受影響。
77str.upcase!
改變 str 的內容為大寫,如果沒有變化則返回 nil。
78str.upto(other_str) { |s| block }
遍歷連續值,以 str 開始,以 other_str 結束(包含),輪流傳遞每個值給 block。String#succ 方法用於生成每個值。

字串 unpack 指令

下表列出了方法 String#unpack 的解壓指令。

指令返回描述
AString移除尾隨的 null 和空格。
aString字串。
BString從每個字元中提取位(首先是最高有效位)。
bString從每個字元中提取位(首先是最低有效位)。
CFixnum提取一個字元作為無符號整數。
cFixnum提取一個字元作為整數。
D, dFloat把 sizeof(double) 長度的字元當作原生的 double。
EFloat把 sizeof(double) 長度的字元當作 littleendian 位元組順序的 double。
eFloat把 sizeof(float) 長度的字元當作 littleendian 位元組順序的 float。
F, fFloat把 sizeof(float) 長度的字元當作原生的 float。
GFloat把 sizeof(double) 長度的字元當作 network 位元組順序的 double。
gFloat把 sizeof(float) 長度的字元當作 network 位元組順序的 float。
HString從每個字元中提取十六進位制(首先是最高有效位)。
hString從每個字元中提取十六進位制(首先是最低有效位)。
IInteger把 sizeof(int) 長度(通過 _ 修改)的連續字元當作原生的 integer。
iInteger把 sizeof(int) 長度(通過 _ 修改)的連續字元當作有符號的原生的 integer。
LInteger把四個(通過 _ 修改)連續字元當作無符號的原生的 long integer。
lInteger把四個(通過 _ 修改)連續字元當作有符號的原生的 long integer。
MString引用可列印的。
mStringBase64 編碼。
NInteger把四個字元當作 network 位元組順序的無符號的 long。
nFixnum把兩個字元當作 network 位元組順序的無符號的 short。
PString把 sizeof(char *) 長度的字元當作指標,並從引用的位置返回 \emph{len} 字元。
pString把 sizeof(char *) 長度的字元當作一個空結束字元的指標。
QInteger把八個字元當作無符號的 quad word(64 位)。
qInteger把八個字元當作有符號的 quad word(64 位)。
SFixnum把兩個(如果使用 _ 則不同)連續字元當作 native 位元組順序的無符號的 short。
sFixnum把兩個(如果使用 _ 則不同)連續字元當作 native 位元組順序的有符號的 short。
UIntegerUTF-8 字元,作為無符號整數。
uStringUU 編碼。
VFixnum把四個字元當作 little-endian 位元組順序的無符號的 long。
vFixnum把兩個字元當作 little-endian 位元組順序的無符號的 short。
wIntegerBER 壓縮的整數。
X 向後跳過一個字元。
x 向前跳過一個字元。
ZString和 * 一起使用,移除尾隨的 null 直到第一個 null。
@ 跳過 length 引數給定的偏移量。

例項

嘗試下面的例項,解壓各種資料。

"abc \0\0abc \0\0".unpack('A6Z6') #=> ["abc", "abc "] "abc \0\0".unpack('a3a3') #=> ["abc", " \000\000"] "abc \0abc \0".unpack('Z*Z*') #=> ["abc ", "abc "] "aa".unpack('b8B8') #=> ["10000110", "01100001"] "aaa".unpack('h2H2c') #=> ["16", "61", 97] "\xfe\xff\xfe\xff".unpack('sS') #=> [-2, 65534] "now=20is".unpack('M*') #=> ["now is"] "whole".unpack('xax2aX2aX1aX2a') #=> ["h", "e", "l", "l", "o"]