字串型態


在Ruby中要表示字串,看似可以使用雙引號或單引號來包括字元序列,字串是String類 別的實例。例如:
>> "Justin"
=> "Justin"
>> 'Justin'
=> "Justin"
>> "Just'in"
=> "Just'in"
>> 'Just"in'
=> "Just\"in"
>> "Just" "in"
=> "Justin"
>>


注意'Just"in'時, 實際上相當於"Just\"in"\"表 示忽略(Escape)字元,因為"被用來作為括住字串的表示法,如果要在字串中表示", 就必須寫為\", 直譯器看到\會忽略下一個字元,不作為語法的一部份。另外還有一些常用的忽略字元表示:
\\ 反斜線
\' 單引號 '
\" 雙引號 "
\0oo 以8 進位數指定字元
\xhh 以16進 位數指定字元
\uhh 以Unicode 16位元編碼指定字元
\Uhh 以Unicode 32位元編碼指定字元
\0 空字元
\n 換行
\r 歸位
\t Tab


實際上Ruby中的字串,應該都是使用雙引號括住,單引號括住的字串,實際上是讓你不用撰寫\\、 \"忽略字元,就可以代 表\、"的簡便方式。例如:
>> 'Just\in'
=> "Just\\in"
>> print 'Just\in'
Just\in=> nil
>> 'Just"in'
=> "Just\"in"
>> print 'Just"in'
Just"in=> nil
>>


如上所示,如果你想顯示Just\in的結果,使用'Just\in', 實際會被轉換為"Just\\in",如果你想顯示Just"in,使用'Just"in', 實際會被轉換為"Just\"in",也因此,在單引號中,除了\\\'之外,撰寫其它忽略字元都會被當作原始字串(Raw string)。例如:
>> 'Just\'in'
=> "Just'in"
>> print 'Just\'in'
Just'in=> nil
>> 'Just\\in'
=> "Just\\in"
>> print 'Just\\in'
Just\in=> nil

>> 'Just\nin'
=> "Just\nin"
>> print 'Just\nin'
Just\nin=> nil
>>


雙引號字串中若包括#{},則#{}中的內容會被當作程式解釋。例如:
>> name = "Justin"
=> "Justin"
>> "My name is #{name}"
=> "My name is Justin"
>> "My name is #{1 + 1}"
=> "My name is 2"
>> "#{def hello; puts 'hello'; end; hello}"
hello
=> ""
>>


被單引號括住的字串,不會對#{}中的內容解譯。例如:
>> name = "Monica"
=> "Monica"
>> "My name is #{name}"
=> "My name is Monica"
>> 'My name is #{name}'
=> "My name is \#{name}"
>>


如果想建立的字串中,同時要含有雙引號與單引號,可以使用%Q%q比 較方便,%Q相當於建立雙 引號字串,%q相當於建立單引號字串。%Q與%q搭配{}||都可以。例如:
>> %Q{"test" and 'test'}
=> "\"test\" and 'test'"
>> %q{"test" and 'test'}
=> "\"test\" and 'test'"
>> %Q|"test" and 'test'|
=> "\"test\" and 'test'"
>> %q|"test" and 'test'|
=> "\"test\" and 'test'"
>> name = "Monica"
=> "Monica"
>> %Q{My name is #{name}}
=> "My name is Monica"
>> %q{My name is #{name}}
=> "My name is \#{name}"
>>


撰寫字串時,可以在雙或單引號中直接Enter換行,字串會自動加上\n, 如果包括縮排用的空白,空白也會是最後字串的一部份。例如:
>> "This is
  a test. This is
  a test!"
=> "This is\n  a test. This is \n  a test!"
>>


如果你想知道字串的字元長度,則可以使用length方法(自 Ruby 1.9.2 開始)。例如:
>> "Justin".length
=> 6

如果想要逐一取得字元,可以使用each_char方 法:
>> "Justin".each_char do |c|
?>     print c, "-"
>> end
J-u-s-t-i-n-=> "Justin"
>>


或者是使用include?方 法測試是否包括某些字串:
>> "Justin".include? "Just"
=> true
>>

可以使用+操 作來串接字串,使用*可以重複字串:
>> text1 = "Just"
=> "Just"
>> text2 = "in"
=> "in"
>> text1 + text2
=> "Justin"
>> text1 * 10
=> "JustJustJustJustJustJustJustJustJustJust"
>>

在強弱型別的光譜中,Ruby比較偏強型別,型態較不能自行轉換,例如Ruby中,不能混合字串與數字進行+運算,你得自己使用to_s方 法,將數字轉為字串,才可以進行字串串接:
>> "score: " + 90
TypeError: can't convert Fixnum into String
        from (irb):13:in `+'
        from (irb):13
        from C:/Winware/Ruby192/bin/irb:12:in `<main>'
>> "score: " + 90.to_s
=> "score: 90"
>>

+實際會產生新的字串,不過在Ruby中,字串是可變動的(Immutable),例如可使用<<在 原字串後附加字串:
>> text1 = "Just"
=> "Just"
>> text1 << "in"
=> "Justin"
>> text1
=> "Justin"
>>

如果你想知道某個字元的編碼,則可以使用ord方法,使用chr方法則可以將指定編 碼轉換為字元:
>> "A".ord
=> 65
>> 65.chr
=> "A"
>>

字串是由字元序列所組成,如果你想要取得字串中某個字元,則可以使用[]指 定索引,索引從0開始。例如:
>> name = "Justin"
=> "Justin"
>> name[0]
=> "J"
>> name[1]
=> "u"
>> name[-1]
=> "n"
>>

Ruby中的索引,不僅可指定正值,還可以指定負值,實際上了解索引意義的開發人員,都知道索引其實就是相對第一個元素的偏移值,在Ruby中,正值 索引就是指正偏移值,負值索引就是負偏移值,也就是-1索引就是倒數第一個元素,-2索引就是倒數第二個元素。

[]操 作還可以進行切片(Slice)運算。例如:
>> name
=> "Justin"
>> name[0..2]
=> "Jus"
>> name[0...2]
=> "Ju"
>> name[3..-1]
=> "tin"
>> name[-5..-2]
=> "usti"

>> name[0, 4]
=> "Just"
>>

[n..m]是指定起始索引與結束索引,且包括結束索引,以取得子字串,[n...m]是指定起始索引與結束索引,但不包括結束索引(實際上n..m 或n...m建立了Range實例,之後會再說明),[n,length]是指定起始索引與長度以取得子字串,由於可指定負值,因此 name[-5..-2]就相當於指定name[1..4]。

先前談過,Ruby中的字串是可以變動的,你也可以使用[]指定索引變動字串內容:
>> name
=> "Justin"
>> name[0] = "j"
=> "j"
>> name
=> "justin"
>> name[1..3] = "ava"
=> "ava"
>> name
=> "javain"
>> name[0, 4] = "Just"
=> "Just"
>> name
=> "Justin"
>> name[0..-1] = "Java"
=> "Java"
>> name
=> "Java"
>> name[1..0] = "-"
=> "-"
>> name
=> "J-ava"
>> name[3, 0] = "-"
=> "-"
>> name
=> "J-a-va"
>> name[5...0] = "-"
=> "-"
>> name
=> "J-a-v-a"
>>

[n..m]、[n...m]或[n, length]右邊接上=,表示作取代的動作,如果指定了[n..0]、[n...0]或[n, 0],則是技巧性地作了安插的動作。

如果想要取代字串,也可以使用[] 時指定被取代字串。例如:
>> slogan = "I love Java"
=> "I love Java"
>> slogan["Java"] = "Ruby"
=> "Ruby"
>> slogan
=> "I love Ruby"
>> slogan["love"] = "am learning"
=> "am learning"
>> slogan
=> "I am learning Ruby"
>>

如果想要反轉字串,可以使用reverse方法,這會傳回新字 串,內容為原字串反轉後的結果,如果使用reverse!方法, 則會在原字串上反轉:
>> name
=> "Java"
>> name2 = name.reverse
=> "avaJ"
>> name
=> "Java"
>> name2
=> "avaJ"
>> name.reverse!
=> "avaJ"
>> name
=> "avaJ"
>>

Ruby的慣例中,如果同時提供有name與name!兩種方法,有!結尾的方法代表著要注意它 與無!方法有所不同。例如,字串上沒!的方法表示以新字串傳回結果,有!的方法表示會修改原字串,像是轉大寫就有upcase與 upcase!方法,轉小寫會有downcase與downcase!方法,裁剪字串尾端字元的chomp與chomp!等方法。

Ruby慣例中,有提供!的方法,就會有提供對應的無!方法。例如,有abc!方法,慣例上就會有個abc方法,不會只單獨定義一個cde!方法,而 沒有對應的cde方法。有經驗的Ruby程式開發人員,看到xyz!,就會去思考它與xyz方法有什麼不同。