-
散列类
-
新建hash:
-
a = {}
a = {键: 值}
-
a = Hash.new(x)
(这里可以设置一个默认值)。
-
-
值的获取与设定
-
fetch
&store
一个用来取一个用来存,基本和a["s"]
的作法一样,但:用下面两个方法可以
- 设默认值
- 添加block
a.store("s1", "Ruby") a.fetch("s2", "undef") #=> "undef" (找不到,所以默认值) a.fetch("s2"){String.new} #=> "" (这里还可以用block)
-
-
hash的迭代器。
数组形式 迭代器形式 keys each_key{|键| …… } Values each_value{|值| …… } to_a each{|键,值| …… } each{|数组| …… } -
hash的默认值。好处:取不存在的值时,不至于发生错误。
-
创建hash时指定默认值:
h = Hash.new(1) h["a"] = 10 h["a"] #=> 10 h["b"] #=> 1
-
创建hash时增加一个block:
h = Hash.new do |hash,key| hash[key] = key.upcase end h ["a"] = "b" p h["a"] #=> "b" p h["b"] #=> "B" p h["c"] #=> "C" 当找不到这个值时,就会自动去执行这个block
-
用fetch方法指定默认值:
h = Hash.new do |hash.key| hash[key] = key.upcase end p h.fetch("x", "(undef)") #=> "(undef)" 同时两个默认值的方法,fetch的优级级会高
-
-
判断是否为某个Hash的
键
or值
- 键
h.key?(key)
h.has_key?(key)
h.include?(key)
h.member?(key)
- 值
h.value?(value)
h.has_value?(value)
- 键
-
查看Hash的大小
-
h.size
&h.length
h = {"a" => "b", "c" => "d"} h.size #=> 2
h.empty?
-
-
删除值:
h.delete(key)
h.delete_if{|key, val| … }
-
h.reject!{|key, val| … }
当不符合时,
delete_if
会返回原来的Hash,reject!
会返回一个nil
-
初始化散列
-
h.clear
清空使用过的散列那这个东西和
h = Hash.new
有什么区别呢?在引用的时候要注意下,请看图:
我忘记了一个超级方便的排序方法:
sort
PS:比起之学VB时的什么泡沫排序法之类的,这里简直不能太好!
-
正在表达式(Regexp类)
-
正则表达式的创建:
re = Regexp.new("Ruby") #=> /Ruby/
%r(模式)
%r<模式>
%r|模式|
%r!模式!
-
判断某个字符串是否匹配:
正则表达式 =~ 字符串
匹配:返回匹配的起始位置
-
不匹配:返回nil
还可以:用
!~
来颠倒结果。 -
进一步应用:
if 正则表达式 =~ 字符串 匹配时的处理 else 不匹配时的处理 end
-
匹配行首与行尾:
^, $
分别表示匹配行首与行尾:像这样的特殊字符称为:元字符。
\A,\z
分别表示匹配字符串头与尾:\z
\Z
两者的区别p "abc\n".gsub(/\z/, "!") => "abc\n!" p "abc\n".gsub(/\Z/, "!") => "abc!\n!"
:大写的
\Z
,如果最后一个是换行符,则会同时匹配换行符与前一个字符。 -
匹配某一个字符:
-
[AB]
:匹配A 或B -
[ABC]
:匹配A,B,C中的一个 -
[012ABC]
:匹配0,1,2,A,B,C中的一个 -
[A-Z]
:匹配A~Z中的一个 -
[ABC][BC]
: 匹配一个两位数,第一个数为A,B,C中的一个,第二位数为B,C中的一个。 -
[A_-]
:匹配A
_
-
中的一个。 -
[^ABC]
:匹配除A,B,C外的任意一位数。 -
.
:万能通配符,相当于五笔中的z
-
-
反斜杠模式
\s
: 匹配空格,制表符, 换行符,换页符\d
:匹配0到9的数字。\w
:匹配英文字与数字。\A
:匹配字符串的开头。\z
:匹配字符串的末尾。-
\
:后面如果跟着:^
$
[
等字符时,可以为这些字符转义再匹配。如:模式 字符串 匹配部分 /ABC[/ "ABC[" "▶ ABC[ ◀" /^ABC/ "ABC" (不匹配) /^ABC/ "012^ABC" "012▶^ABC ◀"
-
重复模式:(单个字符)
-
*
:重复0次以上。可以重复很多次也可以直接没有 -
+
:重复1次以上。至少有一次以上 -
?
:重复0次或1次。可有可无不重复,前后的匹配还是要的!
-
-
最短匹配:
上面6中和重复匹配会最可能匹配更多的字符。
-
最短匹配:加上一个
?
,在第一次匹配时就停止,匹配最短的字符。也叫贪婪匹配与懒惰匹配。
-
使用
()
来重复匹配多个字符。模式 字符串 匹配部分 /^(ABC)*$/ "ABC" "▶ABC ◀" /^(ABC)*$/ "" "▶◀" /^(ABC)*$/ "ABCABC" "▶ABCABC ◀" /^(ABC)*$/ "ABCABCAB" (不匹配) -
使用
|
来多一个匹配选项,可以多选一,也可以全中。模式 字符串 匹配部分 /^(ABC|DEF)$/ "ABC" "▶ABC ◀" /^(ABC|DEF)$/ "DEF" "▶DEF ◀" /^(ABC|DEF)$/ "AB" (不匹配) 使用
quote方法
来转义所有表达式所有字符:
re1 = Regexp.new("abc*def")
re2 = Regexp.new(Regexp.quote("abc*def"))
p (re1 =~ "abc*def") #=> nil
p (re2 =~ "abc*def") #=> 0
-
正则表达式的一些选项:
形式:
/ … / im
-
i
:忽略英文有大小写 -
x
:忽略正则表达式中的空白字符以及 # 后面的字符的选项。指定这个选项后,我们就可以使用 # 在正则表达式中写注释了。 -
m
:使用后可以:用.
匹配换行符了。
-
-
捕获:
-
查看匹配的部分是什么字符串:以
()
的形式/(.)(.)(.)/ =~ "abc" first = $1 second = $2 third = $3 p first #=> "a" p second #=> "b" p third #=> "c"
-
如果是有重复的匹配只会捕获最后一次的字符,如果此时我们想忽略它的捕获,可以这样:以
(?:)
开头就可以忽略捕获。/(.)(\d\d)+(.)/ =~ "123456" p$1 #=> "1" p$2 #=> "45" p$3 #=> "6" /(.)(?:\d\d)+(.)/ =~ "123456" p $1 #=> "1" p $2 #=> "6"
-
另外一种形式:
/C./ =~ "ABCDEF" p $` #=> "AB" p $& #=> "CD" p $' #=> "EF" 这三种可以捕获整个匹配过程的字符
-
-
sub方法与gsub方法:带block
str = "abracatabra" nstr = str.sub(/.a/) do |matched| '<'+matched.upcase+'>' end p nstr #=> "ab
catabra" nstr = str.gsub(/.a/) do |matched| '<'+matched.upcase+'>' end p nstr #=> "ab b " 可以带block,然后把匹配的部分传入block,最后block处理后的结果置换匹配的字符串。
-
直接返回的字符串数组:
scan方法
p "abracatabra".scan(/.a/) #=> ["ra", "ca", "ta", "ra"]
这是纠正一点:转义符号增加的顺序:
/http:\/\// =~ "http://baidu.com" $& #=> "http://"
纠正:
\+要转义的符号
这才是正确的格式。
章节:IO类
这一章节主要对文件内容的操作。暂时不会用到,理解起来也费劲。
章节:File类与Dir类
这一章节主要是对文件夹的操作。暂时不会用到,记起来也很费劲。
章节:Encoding类
这一章节主要是编码类的讲解。暂时不会用到,要用到时再来查看。
第20章 Time类与Date类
-
获取当前时间:
Time.new
Time.now
时间相关的方法:
方法名 意义 year 年 month 月 day 日 hour 时 min 分 sec 秒 usec 秒以下的位数(以毫秒为单位)
to_i 从 1970 年 1 月 1 日到当前时间的秒数 wday 一周中的第几天(0 表示星期天) mday 一个月中的第几天(与 day 方法一样) yday 一年中的第几天(1 表示 1 月 1 日) zone 时区(JST 等) -
指定特定时间:
t = Time.mktime(2017,7,25,16.59,40) #=> 2017-07-25 16:40:00 +0800
-
时间的比较:
-
<
>
-
等,平常的计算比较方法都可以用啦。
-
-
时间的计算:默认直接计算秒数:
t = Time.now p t #=> 2013-03-30 03:11:44 +0900 t2=t+60*60*24 #=>增加24小时的秒数 p t2 #=> 2013-03-31 03:11:44 +0900
-
时间输出的格式:
t.strftime(format)
t.to_s
格式 意义与范围 %A 星期的名称(Sunday 、 Monday ......) %a 星期的缩写名称(Sun 、 Mon ......) %B 月份的名称(January 、 February ......) %b 月份的缩写(Jan 、 Feb ......) %c 日期与时间 %d 日(01 ~ 31) %H 24 小时制(00 ~ 23) %I 12 小时制(01 ~ 12) %j 一年中的天(001 ~ 366) %M 分(00 ~ 59) %m 表示月的数字(01 ~ 12) %p 上午或下午(AM、PM) %S 秒(00 ~ 60) %U 表示周的数字。以星期天为一周的开始(00 ~ 53) %W 表示周的数字。以星期一为一周的开始(00 ~ 53) %w 表示星期的数字。0 表示星期天(0 ~ 6) %X 时间 %x 日期 %Y 表示西历的数字 %y 西历的后两位(00 ~ 99) %Z 时区( JST 等) %z 时区(+0900 等) %% 原封不动地输出 % 示例:
t = Time.now.strftime("%Y-%m-%d") #=> "2017-7-25"
另外两个冷门的格式:(需要引用time类)
t.rfc2822
-
t.iso8601
f
require "time" t = Time.now p t.rfc2822 #=> "Tue, 25 Jul 2017 17:19:00 +0800" p t.iso8601 #=> "2017-07-25T17:19:42+08:00"
-
本地时间与国际时间的切换:
t.utc
t.localtime
t = Time.now p t #=> 2017-07-25 17:21:35 +0800 t.utc #=> 2017-07-25 09:21:35 UTC t.localtime #=> 2017-07-25 17:21:35 +0800
-
从字符串中获取时间:
-
Time.parse(str)
require "time" p Time.parse("2017-7-25") #=> 2017-07-25 00:00:00 +0800
-
-
日期的获取:Date类,适合只需日期不需时间的操作。
Date.today
计算:直接加减默认计算天数
-
同样也有各种方法:
d = Date.today p d.year pd.month pd.day p d.wday p d.mday pd.yday # 年 => 2017 #月 => 7 #日 => 25 # 一周中的第几天(0 表示星期天) # 一个月中的第几天(与 day 方法一样) => 30 #一年中的第几天(1表示 1月 1日) =>206
-
用指定日期生成Date对象:
d = Date.new(2017,7,25) puts d #=> 2017-7-25
还可以用
-1
-2
表示末尾的第几天:d = Date.new(2017,7,-1) #=> 2017-7-31 7月月尾 d = Date.new(2017,7,-2) #=> 2017-7-30 7月月尾前一天
-
Date类的运算:
- 正常的加减,默认会以天数为单位计算
-
>>
<<
会以月份为单位进行运算。
Date类的格式:
- 与前面的Time类一致。
- 从字符串中获取Date类:
- 和Time类一致:
Date.parse(str)
- 和Time类一致:
Proc类
-
什么是proc类,
把block块变成一个对象,这个对象所属的类就是Proc类。这样可以方便我们在后面的调用。
-
创建方法:
Proc.new(…)
proc{}
-
调用方法:
利用
Proc#call
方法-
利用
Proc[]
方法sayhello = Proc.new do |name| puts "Hello, #{name}." end sayhello.call("World") #=> Hello, World. sayhello["World"] #=> Hello, World.
-
另一种写法:
lambda
lambda
还有另外一种写法:-> (块变量){处理}
prc1 = Proc.new do |a, b, c| p [a, b, c] end prc1.call(1,2) #=> [1, 2, nil] prc2 = lambda do |a, b, c| p [a, b, c] end prc2.call(1,2) #=> 错误 (ArgumentError)
lambda
proc
两者的区别:- lambda的参数数量要对应否则会出错,proc的参数数量则没有那么严格。
- lambda可以使用return将值从块中返回。
proc类可以接收块
-
proc的特征:
具有闭包的特征。 闭包:将处理内容、变量等环境同时进行保存的对象,在编程语言中称为闭包(closure)。
-
proc的实例方法:
prc.call(args,…)
prc[args, … ]
prc.yield(args, … )
prc.(args, … )
prc === arg
prc = Proc.new{|a, b| a + b} p prc.call(1, 2) #=> 3 p prc[3, 4] #=> 7 p prc.yield(5, 6) #=> 11 p prc.(7, 8) #=> 15 p prc === [9, 10] #=> 19
fizz = proc{|n| n % 3 == 0 } buzz = proc{|n| n % 5 == 0 } fizzbuzz = proc{|n| n % 3 == 0 && n % 5 == 0} (1..100).each do |i| case i when fizzbuzz then puts "Fizz Buzz" when fizz then puts "Fizz" when buzz then puts "Buzz" else puts i end end
-
prc.arity
: 返回块变量的个数。 -
prc.parameters
-
prc.lambda?
:判断是否通过lambda定义的方法。 -
prc.source_location
: 返回值为[代码文件名,行编号]