語法

字串有四種使用方式:

  1. 單引號
  2. 雙引號
  3. Heredoc
  4. 百分比符號 (%)

以下逐一進行介紹

單引號

以兩個單引號包夾一段文字,表示字串內容,使用單引號的字串有一些特徵如下 (與雙引號比較):

  1. 逸出字元 (Escape characters) 只有兩種。
  2. 逸出字元 \\ 可省略寫作 \,但不可為最後一個字元 (不建議省略)。
  3. 不會對字串中的程式進行解析。

所謂逸出字元是為了某些特別的用途或能以此輸入打不出來的字,而定義的一種使用方式,在此的逸出字元以反斜線 (backslash) 開頭。例如,我們使用單引號做包夾,但字串中如果出現單引號,將會誤判為字串結束單引號,所以使用 \' 來表示字串中的單引號。使用單引號的字串可用的逸出字元如下:

符號說明
'單引號字元。
\反斜線字元。

一些使用範例如下:

1
2
3
4
5
6
7
8
9
10
11
12
puts '基本用法';
puts '也可以
斷行';
puts 'You\'re a good man.'; # You're a good man.
puts 'C:\\ruby'; # C:\ruby
puts 'C:\ruby'; # C:\ruby
# 不能在最後省略,\' 會被解析為字元而缺少結尾單引號
# puts 'C:\ruby\'; # Parse error
puts 'First line \n second line'; # First line \n second line

text = 123;
puts 'text is #{text}'; # text is #{text}

雙引號

以兩個雙引號包夾一段文字,表示字串內容,最主要的重點是,變數會在雙引號中被解析。雙引號的逸出字元如下:

符號說明
\n換行字元 (LF or 0x0A)。
\s空白字元 (Space)。
\r歸位字元 (CR or 0x0D)。
\t水平Tab字元 (HT or 0x09)。
\v垂直tab字元 (VT or 0x0B)。
\f跳頁字元 (CR or 0x0C)。
\bbackspace 字元 (0x08)。
\abell / alert 字元 (0x07)。
\eescape 字元 (0x1b)。
[0-7]{1,3}以八進位法表示字元。
\x[0-9A-Fa-f]{1,2}以十六進位法表示字元。
\u[0-9A-Fa-f]{4}以十六進位法表示 Unicode 字元。
\x其他非逸出字元會顯示 x 本身。
\cxcontrol-x
\C-xcontrol-x
\M-xmeta-x
\M-\C-xmeta-control-x

一些使用範例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
puts "基本用法";
puts "也可以
斷行";
puts "You're a good man."; # You're a good man.
puts "C:\\ruby"; # C:\ruby

puts "First line\nsecond line";
# output:
# First line
# second line

text = 123;
puts "text is #{text}"; # text is 123
puts "text is \#{text}"; # text is #{text}

Heredoc

Heredoc 使用 << 符號開始,後面接著一個自訂的標籤,最後以自訂的標籤作結束。

開頭的標簽有三種寫法,影響內容的解析:

  1. 不含引號,效果同雙引號字串。
  2. 單引號字串,內容解析處理同單引號字串,類似PHP的nowdoc。
  3. 雙引號字串,內容解析處理同雙引號字串。

內容的解析處理包含逸出字元和程式解析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
text = "hello"

# 開頭標籤必須緊跟在<<之後
puts <<EOT
\t<a href="http://tw.yahoo.com">Yahoo's web</a><br/>\n
text is #{text}<br/>
EOT
EOT
# 結尾標籤之前不能有任何字元

puts <<"EOT"
\t<a href="http://tw.yahoo.com">Yahoo's web</a><br/>\n
text is #{text}<br/>
EOT
EOT

puts <<'EOT'
\t<a href="http://tw.yahoo.com">Yahoo's web</a><br/>\n
text is #{text}<br/>
EOT
EOT

結果輸出

1
2
3
4
5
6
7
8
9
10
11
  <a href="http://tw.yahoo.com">Yahoo's web</a><br/>

text is hello<br/>
EOT
<a href="http://tw.yahoo.com">Yahoo's web</a><br/>

text is hello<br/>
EOT
\t<a href="http://tw.yahoo.com">Yahoo's web</a><br/>\n
text is #{text}<br/>
EOT

如果結尾標簽希望能夠縮排,可使用 <<- 的寫法

1
2
3
puts <<-EOT
This is a test
EOT

另外 <<XXX 本身其實可以視為一個變數進行處理:

1
2
3
4
5
6
7
8
9
puts <<EOT * 3
This is a test
EOT

puts <<PartA + <<PartB
This is a PartA
PartA
This is a PartB
PartB

結果輸出

1
2
3
4
5
This is a test
This is a test
This is a test
This is a PartA
This is a PartB

百分比符號

另一用法是利用百分比 (%) 開頭,加上任意的符號 (非字母數字) 包夾字串內容,共有三種用法:

  1. %{xxx},解析內容
  2. %q{xxx},不解析內容
  3. %Q{xxx},同1,解析內容

規則和單引號雙引號類似,如下範例:

1
2
3
4
5
6
7
8
9
10
11
text = 123

puts %{可以
斷行
也可以輸出變數#{text}}

puts %[可以用各種包夾符號] # 可以用各種包夾符號
puts %(I'm "OK"\(逸出括號\)) # I'm "OK"(逸出括號)

puts %q{text = #{text}} # text = #{text}
puts %Q{text = #{text}} # text = 123

程式解析

字串中可使用 #{expr} 的形式插入程式碼,稱為 Interpolation,通常用來填入變數,不過也可以執行程式:

1
2
3
value = 2 * 5
puts "2 * 5 = #{value}" # 2 * 5 = 10
puts "2 * 5 = #{2 * 5}" # 2 * 5 = 10

字串的操作

字元的存取修改

字串可簡單視為字元的陣列,可以用陣列的索引方式取得或修改某個字元。用法範例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
str = "I lose"
str2 = str

puts str[4] # s
str[4] = 'v'
puts str # I love
p str[7] # nil, 超出陣列範圍

# str[7] = 'u' # error, 超出陣列範圍

str[-3] = 'a'
puts str # I lave, 負索引從後面計算
puts str2 # I lave, Ruby 的字串使用 pass by reference!!

str2 += 'd'
puts str # I lave, 接合字串將產生新物件

str2 = str

str << 'd'
puts str2 # I laved, append 字串的用法, 修改物件

str << 46
puts str # I laved., 數字會被視為位碼

其中特別要注意的地方是,Ruby 的物件導向將字串也視為一個物件,當他指派給新的變數的時候只會得到他的記憶體參考位址,所以修改字串內容將會影響到所有參考的變數!

字串的連接

字串可以簡單利用加號 (+) 來連接,有別於其他程式語言,數字等型別必須先轉成字串來能連接:

1
2
3
4
5
6
7
hello = "Hello"
str = hello + " world."
puts str # Hello world.

puts hello + nil.to_s # Hello
puts hello + true.to_s # Hellotrue
puts hello + 123.to_s # Hello0

轉型

字串可以使用以下轉型函式:

  1. to_i: 轉整數
  2. to_f: 轉浮點數
  3. to_sym: 轉符號

如下範例:

1
2
3
4
5
6
7
p "169.99cm".to_f   # 169.99
p "169.99cm".to_i # 169
p "169.99cm".to_sym # :"169.99cm"

p "".to_f # 0.0
p "".to_i # 0
# p "".to_sym # error

從上可以看到,轉數字部分會取出前面符合的部分,

延伸閱讀

上一篇 Ruby 教學 - 數字 (Numeric)
下一篇 Ruby 教學 - 符號 (Symbol)