ruby標準類型
一、數字
- Ruby支援整數和浮點數,整數可以是任意長度
- 一定範圍內的整數以二進位存放,它們屬於fixnum類型,當超出這個範圍時則自動轉換為bignum類型
- 表達方式:符號+一串字元,數字串中的底線會被忽略,(首碼包括:0表示八進位, 0x表示十六進位, 0b表示二進位)123_456_789_123_345_789 # Bignum
0xaabb # 十六進位
- 也可以通過在前面加上問號來得到ASCII碼字元對應的整數值和逸出序列的值
?a # 一般字元
?/n # 分行符號 (0x0a)
?/C-a # CTRL+a (0x01)
?/M-a # ALT+a
?/M-/C-a # CTRL+ALT+a
?/C-? # 刪除鍵
- 一個帶小數點的數字字面值被轉換成Float對象
- 所有的數字都是對象,不存在相應的函數而是方法
exp:
數位絕對值是aNumber.abs而不是abs(aNumber)
- 整數有用的迭代器
3.times { print "X " } => X X X 1.upto(5) { |i| print i, " " } =>1 2 3 4 5 99.downto(95) { |i| print i, " " }=>99 98 97 96 95 50.step(80, 5) { |i| print i, " " }=>50 55 60 65 70 75 80
二、字串
- Ruby的字串是8位位元組的簡單序列,字串是String類的對象
- 注意轉換機制(注意單引號與雙引號的區別),如:
單引號中兩個相連的反斜線被替換成一個反斜線,,一個反斜線後跟一個單引號被替換成一個單引號
'escape using "//"' >> 轉義為"/" 'That/'s right' >> That's right
- 雙引號支援多義的轉義
"/n"
#{expr}序列來替代任何的Ruby運算式的值 ,(全域變數、類變數或者執行個體變數,那麼可以省略大括弧)
"Seconds/day: #{24*60*60}" >> Seconds/day: 86400 "#{'Ho! '*3}Merry Christmas" >> Ho! Ho! Ho! Merry Christmas "This is line #$." >> This is line 3
- here document來建立一個字串,end_of_string 為結束符號
aString = <<END_OF_STRING The body of the string is the input lines up to one ending with the same text that followed the '<<' END_OF_STRING
- %q和%Q分別把字串分隔成單引號和雙引號字串(即%q與%Q後面的符號具有',"的功能)
%q/general single-quoted string/ >> general single-quoted string
- String 常用功能
String#split:把行分解成欄位
String#chomp:去掉分行符號
String#squeeze:剪除被重複輸入的字元
String#scan:以指定想讓塊匹配的模式
exp:
/jazz/j00132.mp3 | 3:45 | Fats Waller | Ain't Misbehavin'
/jazz/j00319.mp3 | 2:58 | Louis Armstrong | Wonderful World
#檔案格式如上,要進行分解
songs = SongList.new
songFile.each do |line|
file, length, name, title = line.chomp.split(//s*/|/s*/)#先chomp,後再分解,//s*表示任字元
name.squeeze!(" ")#替換空格
mins, secs = length.scan(//d+/)#這裡用scan匹配模式
songs.append Song.new(title, name, mins.to_i*60+secs.to_i)
end
三、
區間
- 區間存在於任何地方,如:1到12月。ruby用區間實現了3個不同的特性:序列,條件,間隔。
- "..":兩個點號建立一個閉區間,"...":而三個點號建立一個右開區間(即右邊界不取值)
exp:0..anArray.length-1 等同於 0...anArray.length
- to_a 把區間轉換成列表
exp: ('bar'..'bat').to_a >> ["bar", "bas", "bat"]
- 區間的共它的用法
digits = 0..9
digits.include?(5) >> true
digits.min >> 0
digits.max >> 9
digits.reject {|i| i < 5 } >> [5, 6, 7, 8, 9]
digits.each do |digit|
dial(digit)
end
- ruby能把基於自己定義的對象的區間,要求:這個對象必須能夠響應succ方法來返回序列中的下一個對象,並且這個對象必須能夠使用<=>運算子來被比較,即常規的比較子,
- 間隔測試
puts (1..10).include?(3.14)=> ture
puts (1..10) === 3.14 => ture
四、Regex
- Regex是Regexp類型的對象,可以使用構造器顯式地建立一個Regex,也可以使用字面值形式/pattern/和%r/pattern/來建立
- 用Regxp#match(aString)的形式或者匹配運算子=~(正匹配)和!~(負匹配)來匹配字串了。匹配運算子在String和Regexp中都有定義,如果兩個運算元都是字串,則右邊的那個要被轉換成Regex
exp:
a = "Fats Waller"
a =~ /a/ >> 1
a =~ /z/ >> nil
a =~ "ll" >> 7
- 上面返回的是匹配字元的位置,其它
$&接受被模式比對到的字串部分
$`接受匹配之前的字串部分
$'接受之後的字串。
exp:下面的方法後繼都會用到
def showRE(a,re)
if a =~ re
"#{$`}<<#{$&}>>#{$'}" #返回前、中、後
else
"no match"
end
end
- 模式,任何一個運算式都包含一個模式,它用來把Regex和字任串匹配
模式中除了., |, (, ), [, {, +, /, ^, $, *,和?以外的字任都匹配它自己
如果要匹配這些特殊的字元就需要加上反斜線做首碼,分析上面例字
//s*/|/s*/,在/s與|之前都加了/做首碼。
showRE('kangaroo', /angar/) >> k<<angar>>oo
showRE('!@%&-_=+', /%&/) >> !@<<%&>>-_=+
showRE('yes | no', //|/) >> yes <<|>> no
- /後跟一個字母或數字表示一個特定的結構如/s表示字元等。
- 錨點 一個Regex總是返回找到模式的第一個匹配,如何改變?
模式^和$分別用來匹配行首和行尾
序列/A匹配字串開始的位置,/z和/Z匹配字串結尾的位置
/b和/B分別匹配字邊界和非字邊界
showRE("this is/nthe time", /^the/) >> this is/n<<the>> time
showRE("this is/nthe time", /is$/) >> this <<is>>/nthe time
showRE("this is/nthe time", //Athis/) >> <<this>> is/nthe time
五、字元類
- 這裡的字元類不是物件導向的類,只表示這些這字元屬於一個特殊的種類
- 字元類是用方括弧擴起來的字元的集合:[characters]匹配方括弧中的所有單字元。[aeiou]匹配母音,[,.:'!?]匹配標點符號等等
showRE('It costs $12.', /[aeiou]/) >> It c<<o>>sts $12.
- 在方括弧中的序列c1-c2表示在c1-c2之間也包括c1和c2的所有字元
a = 'Gamma [Design Patterns-page 123]'
showRE(a, /[]]/) >> Gamma [Design Patterns-page 123<<]>>
showRE(a, /[B-F]/) >> Gamma [<<D>>esign Patterns-page 123]
showRE(a, /[-]/) >> Gamma [Design Patterns<<->>page 123]
showRE(a, /[0-9]/) >> Gamma [Design Patterns-page <<1>>23]
- 緊跟在開括弧([)後的是字元^,這表示這個字元類的否定:[^a-z]匹配任何不是小寫字母的字元。
- 字元類縮寫
序列 形如 [ ... ] 含義
/d [0-9] Digit character
/D [^0-9] Nondigit
/s [/s/t/r/n/f] Whitespace character 匹配一個單空白符
/S [^/s/t/r/n/f] Nonwhitespace character
/w [A-Za-z0-9_] Word character
/W [^A-Za-z0-9_] Nonword character
- 重複
r * 匹配0個或多個r的出現
r + 匹配一個或多個r的出現
r ? 匹配0個或1個r的出現
r {m,n} 匹配最少m最多n個r的出現
r {m,} 匹配最少m個r的出現重複結構有高優先權:即它們僅和模式中的直接Regex前驅捆綁
/ab+/匹配一個"a"後跟一個活著多個"b",而不是"ab"的序列
/a*/會匹配任何字串:0個或者多個"a"的任一字元串。
exp:
a = "The moon is made of cheese"
showRE(a, //w+/) >> <<The>> moon is made of cheese
showRE(a, //s.*/s/) >> The<< moon is made of >>cheese
showRE(a, //s.*?/s/) >> The<< moon >>is made of cheese
showRE(a, /[aeiou]{2,99}/) >> The m<<oo>>n is made of cheese
showRE(a, /mo?o/) >> The <<moo>>n is made of cheese
- 替換
"|"既匹配它前面的Regex或者匹配後面的
a = "red ball blue sky"
showRE(a, /d|e/) >> r<<e>>d ball blue sky
showRE(a, /al|lu/) >> red b<<al>>l blue sky
showRE(a, /red ball|angry sky/) >> <<red ball>> blue sky
- 分組
圓括弧把Regex分組,組中的內容被當作一個單獨的Regex
showRE('banana', /(an)+/) >> b<<anan>>a
# 匹配重複的字母
showRE('He said "Hello"', /(/w)/1/) >> He said "He<<ll>>o"
# 匹配重複的子字串
showRE('Mississippi', /(/w+)/1/) >> M<<ississ>>ippi
- 基於模式的替換
你是否想過,大小寫替換。
方
法String#sub和String#gsub都在字串中搜尋匹配第一個參數的部分,然後用第二個參數來替換它們。String#sub只替換一次,
而String#gsub替換所有找到的匹配。都返回一個包含了替換的新的字串的拷貝。進化版本是String#sub!和 String#gsub!
a = "the quick brown fox"
a.sub(/[aeiou]/, '*') >> "th* quick brown fox"
a.gsub(/[aeiou]/, '*') >> "th* q**ck br*wn f*x"
a.sub(//s/S+/, '') >> "the brown fox"
a.gsub(//s/S+/, '') >> "the"
第二個參數可以是代碼塊
a = "the quick brown fox"
a.sub (/^./) { $&.upcase } >> "The quick brown fox"
a.gsub(/[aeiou]/) { $&.upcase } >> "thE qUIck brOwn fOx"
- 反斜線序列用在替換中
/& 後面的匹配
/+ 後面的匹配組
/` 匹配前面的字串
/' 匹配後面的字串
// 反斜線的字面值
- 物件導向的Regex
Regex的字面值建立Regexp類
re = /cat/
re.type >> Regexp
方法Regexp#match從字串中匹配一個Regex,如果不成功,方法返回nil,如果成功,返回MatchData類的一個執行個體
exp:
e = /(/d+):(/d+)/ # match a time hh:mm
md = re.match("Time: 12:34am")
md.type >> MatchData
md[0] # == $& >> "12:34"
md[1] # == $1 >> "12"
md[2] # == $2 >> "34"
md.pre_match # == $` >> "Time: "
md.post_match # == $' >> "am"
原電子文檔:http://www.moer.net