字符串
String 与 Symbol 这两个类提供了表示文字与处理文字的功能。这两个类之间很不同。
字符串表示
一个字符串一般用一组引号包装:
"这就是一个字符串"
单引号也行:
'我也是个字符串'
使用字符插值的时候得用双引号:
puts "二加二等于 #{2 + 2}"
puts '二加二等于 #{2 + 2}'
输出的内容是:
二加二等于 4
二加二等于 #{2 + 2}
单引与双引在 escape 时的区别:
puts "Backslashes (\) have to be escaped in double quotes."
puts 'You can just type once in a single quoted string.'
puts "But whichever type of quotation mark you use..."
puts "...you have to escape its quotation symbol, such as "."
puts 'That applies to ' in single-quoted strings too.'
puts 'Backslash-n just looks like n between single quotes.'
puts "But it means newlinenin a double-quoted string."
puts 'Same with t, which comes out as t with single quotes...'
puts "...but inserts a tab character:tinside double quotes."
puts "You can escape the backslash to get \n and \t with double quotes."
输出的是:
Backslashes () have to be escaped in double quotes.
You can just type once in a single quoted string.
But whichever type of quotation mark you use...
...you have to escape its quotation symbol, such as ".
That applies to ' in single-quoted strings too.
Backslash-n just looks like n between single quotes.
But it means newline
in a double-quoted string.
Same with t, which comes out as t with single quotes...
...but inserts a tab character: inside double quotes.
You can escape the backslash to get n and t with double quotes.
下午6:59 **
下午7:24 **
其它的引用机制
还有一种引用机制,%char{text},下面的 %q 生成一个单引号字符:
puts %q{You needn't escape apostrophes when using %q.}
因为上面的字符串不是用单引号标记的,所以字符串里的撇号不用 escape 。
双引号用 %Q,%{} 也可以。分隔符也可以很随便:
%q-A string-
%Q/Another string/
%[Yet another string]
Here 文档
here-doc,可以是多行字符串:
>> text = < >> text = <<-EOM >> text = <<-'EOM' >> a = < >> array = [1,2,3,< do_something_with_args(a, b, < 获取与设置子字符串 [] 操作符可以得到一个字符串里的某个位置上的字符。提供一个索引号就行了,索引号是从零开始的,负数的索引指的是从字符串的最后往前数。 试一下: >> string = 'Ruby is a cool language.' >> string[5,10] >> string[7..14] >> string['cool lang'] >> string[/c[ol ]+/] >> string.slice!('cool') >> string = 'Ruby is a cool language.' >> 'a' + 'b' >> str = 'hi ' >> str = 'hi ' >> str = 'hi' >> "the sum is #{2+2}" >> "My name is #{ >> class Person 查询字符串 查询字符串有几种口味,有的可以给你响应布尔值,有的给你字符串在当前状态下的状态报告 。 布尔 你可以问字符串是不是包含某个子字符串,使用 include? ,试一下: >> string = 'Ruby is a cool language.' >> string.start_with?('Ruby') >> string.empty? 得到字符串的尺寸: >> string.size >> string.length >> string.count('a') >> string.count('g-m') >> string.count('A-Z') >> string.count('aey. ') >> string.count('^aey. ') >> string.count('ag-m') >> string.index('cool') >> 'a'.ord >> 'abc'.ord >> 97.chr 字符串比较与顺序 2016-09-12 08:09 *** String 类里混合了 Comparable 模块,里面定义了 <=> 方法。所以你可以这样: >> 'a' <=> 'b' 'b' 大于 'a','a' 大于 'A',影响顺序的是字符值,'a' 是 97,'A' 是 65 。'.' 是 46,',' 是 44 。 比较是否相等 最常用的方法是 == ,试一下: >> 'string' == 'string' String#eql? 方法也可以测试是否相等。它一般跟 == 是一样的。还有 String#equal? ,一般它比较的是两个对象是不是同一个对象。 >> 'a' == 'a' 字符串变形分成三大类:大小写,格式化,内容变形。 大小写 试试这些: >> string = 'I Love You' >> string = 'i love you' rjust,ljust 方法可以调整字符串的尺寸: >> string = 'I Love You' >> string.rjust(25, '.') >> string.center(25, '*') >> string = ' I Love You ' chop 与 chomp 方法可以删掉字符串结尾。chop 是无条件删除字符,chomp 如果在结尾找到目录子字符串,就会删除它。默认的 chomp 目录子字符是换行符。 试试: >> "I Love You".chop >> string = "I Love You" >> string = "I..." >> "I Love You".delete("oue") >> "I Love You".crypt("34") >> "a".succ 参数是 2-36 这个范围的数字。 >> "100".to_i(17) >> "100".oct >> "1.2345".to_f 源文件的编码 默认是 UTF-8 编码。可以这样确定一下,把下面代码放到一个文件里,然后再运行一下。 puts __ENCODING__ # encoding: encoding # encoding: ASCII >> str = "test string" >> str.encode("US-ASCII") 符号是 Ruby 内置类 Symbol 的实例。它们的字面构造器是前面加冒号: :a >> "a".to_sym >> :a.to_s 符号像字符串,很多时候又像整数。主要特点是:不变性与唯一性。 不变性 符号只要一存在,它就不能被改变。 唯一性 你看到一个符号 :abc,无论你在哪里看到它,它都是同一个对象。 做个实验: >> "abc".object_id 下面代码里包含了一个符号对象 :x ,还有一个本地变量标识符 s : s = :x >> Symbol.all_symbols >> Symbol.all_symbols.size 最常用的是作为方法的参数与 hash key 。 符号作为方法参数 attr_accessor :name "abc".send(:upcase) 符号作为 hash key >> m_hash = { :title => "美丽人生", :year => 1997 } >> m_hash = { "title" => "美丽人生", "year" => 1997 } 下面这个 hash : has = { :title => "美丽人生", :year => 1997 } has = { title: "美丽人生", year: 1997 } 把符号想成是看起来像字符串一样的整数。 数字对象 在 Ruby 里数字也是对象,你可以给它发信息: >> n = 99.6 Numeric >> 1 + 1 >> 0x12 >> 012 >> 1.+(1) 导入 date: >> require 'date' require 'date' 实例化 date/time 对象 创建日期对象 >> today = Date.today >> puts Date.new(1959,2,1) 用 parse 创建日期对象: >> puts Date.parse("2012/7/22") 创建时间对象:new(又叫 now),at,local(又叫 mktime),parse。 >> Time.new DateTime 是 Date 的子类。 >> puts DateTime.new(2009, 1, 2, 3, 4, 5) >> dt = DateTime.now >> d.monday? 所有的 date/time 对象都有 strftime 方法。 >> t = Time.now >> Date.today.rfc2822 Time 有 to_date ,to_datetime 方法,Date 有 to_time,to_datetime 方法,DateTime 有 to_time,to_date 方法。 date/time 算术 >> t = Time.now >> dt = DateTime.now >> d = Date.today >> d = Date.today 11:24 ****
This is the second line.
Now we're done.
EOM
=> "This is the first line of text.nThis is the second line.nNow we're done.n"
<
The EOM doesn't have to be flush left!
EOM
=> "The EOM doesn't have to be flush left!n"
默认 here-docs 跟双引号字符串一样,可以解释它里面的字符插值,还有一些 escape 字符,比如 n 或 t 。如果你需要让 here-doc 像单引号字符串那样,可以这样:
Single-quoted!
Note the literal n.
And the literal #{2+2}.
EOM
=> "Single-quoted!nNote the literal \n.nAnd the literal #{2+2}.n"
>> puts text
Single-quoted!
Note the literal n.
And the literal #{2+2}.
=> nil
这样再试试:
EOM
=> 50
再这样试一下:
It becomes array[3]
EOM
=> [1, 2, 3, "This is the here-doc.nIt becomes array[3]n", 4]
作为方法参数:
EOM
字符串处理
=> "Ruby is a cool language."
>> string[5]
=> "i"
>> string[-12]
=> "o"
截取一段,再给 [] 提供一个 m 参数:
=> "is a cool "
也可以用一个 range 对象作为参数:
=> " a cool "
>> string[-12..-3]
=> "ol languag"
>> string[-12..20]
=> "ol langua"
>> string[15..-1]
=> "language."
也可以直接给出你想得到的子字符串的内容,如果找到了就返回这个字符串,没找到就返回 nil:
=> "cool lang"
>> string['very cool lang']
=> nil
正则表达式:
=> "cool l"
slice 与 slice!:
=> "cool"
>> string
=> "Ruby is a language."
[]= 方法可以设置找到的字符串:
=> "Ruby is a cool language."
>> string['cool'] = 'great'
=> "great"
>> string
=> "Ruby is a great language."
>> string[-1] = '!'
=> "!"
>> string
=> "Ruby is a great language!"
>> string[-9..-1] = 'thing to learn'
=> "thing to learn"
>> string
=> "Ruby is a great thing to learn"
合并字符串
=> "ab"
>> 'a' + 'b' + 'c'
=> "abc"
+ 得到的永远都会是一个新的字符串,这样再试一下:
=> "hi "
>> str + 'there.'
=> "hi there."
>> str
=> "hi "
再试试 << 方法,它会改变原始的字符串:
=> "hi "
>> str << 'there.'
=> "hi there."
>> str
=> "hi there."
通过插值合并字符串
=> "hi"
>> "#{str} there."
=> "hi there."
插值里可以是任何 Ruby 表达式:
=> "the sum is 4"
不信再试试这个:
>> class Person
>> attr_accessor :name
>> end
>> d = Person.new
>> d.name = 'David'
>> d.name
>> }."
=> "My name is David."
更好的方法:Ruby 在插值里会调用对象的 to_s 方法,你可以定义自己的 to_s 方法:
>> attr_accessor :name
>> def to_s
>> name
>> end
>> end
=> :to_s
>> david = Person.new
=> #
>> david.name = 'David'
=> "David"
>> "hello, #{david}!"
=> "hello, David!"
上面的例子里,我们把 david 作为插值,结果就是会调用它的 to_s 。
=> "Ruby is a cool language."
>> string.include?('Ruby')
=> true
>> string.include?('English')
=> false
开始:start_with?,结束:end_with?,再试试:
=> true
>> string.end_with?("!!!")
=> false
问一下字符串在不在:
=> false
>> "".empty?
=> true
内容查询
=> 24
或:
=> 24
看一下指定的字符在字符串里出现了多少次:
=> 3
一个范围的字符一共出现了多少次:
=> 5
因为大小写敏感,所以再试一下:
=> 1
这样再试试:
=> 10
还有否定形式,使用 ^:
=> 14
>> string.count('^g-m')
=> 19
换个花样:
=> 8
>> string.count('ag-m', '^1')
=> 8
查询字符在字符串里的索引,使用 index,反着查,使用 rindex:
=> 10
>> string.index('l')
=> 13
>> string.rindex('l')
=> 15
使用 ord 方法得到字符的序号编码:
=> 97
多个字符的话,只取第一个字符:
=> 97
反过来:
=> "a"
下午9:46 ***
=> -1
>> 'b' > 'a'
=> true
>> 'a' > 'A'
=> true
>> '.' > ','
=> true
<=> 方法在右边对象大的时候会返回 -1 ,左边对象大的时候返回 1 ,两个对象相等的时候返回 0。
=> true
>> 'string' == 'house'
=> false
两个 'string' 是不同的对象,但它们的内容是一样的。
=> true
>> 'a'.eql?('a')
=> true
>> 'a'.equal?('a')
=> false
字符串变形
=> "I Love You"
>> string.upcase
=> "I LOVE YOU"
>> string.downcase
=> "i love you"
>> string.swapcase
=> "i lOVE yOU"
首字母大写 capitalize/capitalize! :
=> "i love you"
>> string.capitalize
=> "I love you"
格式化
=> "I Love You"
>> string.rjust(25)
=> " I Love You"
>> string.ljust(25)
=> "I Love You "
给方法提供第二个参数:
=> "...............I Love You"
>> string.ljust(25, '-')
=> "I Love You---------------"
试试 center 方法:
=> "*******I Love You********"
用 stip,lstrip,rstrip 方法去掉空白:
=> " I Love You "
>> string.strip
=> "I Love You"
>> string.lstrip
=> "I Love You "
>> string.rstrip
=> " I Love You"
内容变形
=> "I Love Yo"
>> "I Love Youn".chomp
=> "I Love You"
>> "I Love You".chomp("u")
=> "I Love Yo"
试一下 clear 的威力:
=> "I Love You"
>> string.clear
=> ""
>> string
=> ""
替换:
=> "I..."
>> string.replace("I Love You")
=> "I Love You"
>> string
=> "I Love You"
删除,参数的规则跟 count 方法的参数规则一样:
=> "I Lv Y"
>> "I Love You".delete("^o")
=> "oo"
>> "I Love You".delete("a-e", "^c")
=> "I Lov You"
crypt,DES 数据加密,它唯一的参数是两位数的 salt 字符:
=> "342C1ro5Q3yLQ"
succ:
=> "b"
>> "abc".succ
=> "abd"
>> "azz".succ
=> "baa"
字符串转换
=> 289
不太明白 to_i 方法的参数的意思,是不是参数表示的是数字的位数,进制?base 17 ?base 8,base 16,不懂进制是什么意思。
8 位:oct,16 位:hex
=> 64
>> "100".hex
=> 256
to_f,转换成浮点不数,to_s,返回接收者,to_sym,intern ,转换成符号。
=> 1.2345
>> "hello".to_s
=> "hello"
>> "abc".to_sym
=> :abc
>> "1.23and some words".to_f
=> 1.23
>> "just some words".to_i
=> 0
字符串编码
改变源文件的编码,可以使用一个 magic 注释在文件的顶部:
比如设置成 US-ASCII:
个别字符串的编码
=> "test string"
>> str.encoding
=> #
设置字符串编码:
=> "test string"
符号
:book
:"Here's how to make a symbol with spaces in it."
用 to_sym 方法创建符号:
=> :a
>> "Coverting string to symbol with intern...".intern
=> :"Coverting string to symbol with intern..."
把符号改换成字符串:
=> "a"
>>
符号的主要特点
=> 70179527234100
>> "abc".object_id
=> 70179527221160
>> :abc.object_id
=> 70179535013580
>> :abc.object_id
=> 70179535013580
符号与标识符
Ruby 的内部会使用符号来跟踪它创建的所有的变量,方法,常量的名字。查看一下:
=> [:inspect, :intern, :object_id, :const_missing, :method_missing,
:method_added, :singleton_method_added, :method_removed,
:singleton_method_removed,
给一个变量或常量分配一个值,创建了一个类,或写一个方法,你选择的标识符都会被 Ruby 放到它的符号表里。我们可以验证一下:
=> 3481
>> abc = 1
=> 1
>> Symbol.all_symbols.size
=> 3481
>> Symbol.all_symbols.grep(/abc/)
=> [:abc]
符号的使用
attr_reader :age
send 方法可以不用点来发送信息,它可以接收一个符号:
send 也可以接收一个字符串参数,比如 upcase。不过你直接提供给它一个符号,就省了 Ruby 的事儿了,不然 Ruby 会在内部把字符串转换成符号。
=> {:title=>"美丽人生", :year=>1997}
>> m_hash[:year]
=> 1997
差不多的 hash,使用的是字符串 key :
=> {"title"=>"美丽人生", "year"=>1997}
>> m_hash["title"]
=> "美丽人生"
符号作为 hash key 更快一些,看起来也比较好。
也可以写成:
字符串与符号的比较
=> 99.6
>> m = n.round
=> 100
>> puts m
100
=> nil
>> x = 12
=> 12
>> if x.zero?
>> puts "x is zero"
>> else
?> puts "x is not zero"
>> end
x is not zero
=> nil
数字类
Float
Integer
Fixnum
Bignum
算术
=> 2
>> 10 / 5
=> 2
>> 16 / 5
=> 3
>> 10 / 3.3
=> 3.0303030303030303
>> 1.2 + 3.4
=> 4.6
>> -12--7
=> -5
>> 10 % 3
=> 1
十六进制整数前面带 0x :
=> 18
>> 0x12 + 12
=> 30
前面带 0 的是八进制整数:
=> 10
>> 012 + 12
=> 22
>> 012 + 0x12
=> 28
大部分算术操作其实都是方法,因为有语法糖所以看起来像是操作符,原本应该是这样的:
=> 2
>> 12./(3)
=> 4
>> -12.-(-7)
=> -5
时间与日期
=> true
>> Date.parse("April 24 1705").england.strftime("%B %d %Y")
=> "April 13 1705"
处理时间与日期的有几个类:Time,Date,DateTime。它们的对象可以叫做 date/time 对象。使用它们先要导入:
require 'time'
第一行提供了 Date 与 DateTime 类,第二行是 Time 类。在未来可能会把跟日期与时间的类组合到一块儿。
=> #
>> today.to_s
=> "2016-09-12"
>> puts today
2016-09-12
=> nil
使用 Date.new 创建日期对象,要给它提供年,月,日:
1959-02-01
如果不提供月与日的话,默认会是 1 。
2012-07-22
>> puts Date.parse("03/6/9")
2003-06-09
>> puts Date.parse("33/6/9")
2033-06-09
>> puts Date.parse("77/6/9")
1977-06-09
>> puts Date.parse("November 2 2013")
2013-11-02
>> puts Date.parse("Nov 2 2013")
2013-11-02
>> puts Date.parse("2 Nov 2013")
2013-11-02
>> puts Date.parse("2013/11/2")
2013-11-02
创建时间对象
=> 2016-09-12 10:47:31 +0800
>> Time.at(100000000)
=> 1973-03-03 17:46:40 +0800
>> Time.mktime(2007,10,3,14,3,6)
=> 2007-10-03 14:03:06 +0800
>> require 'time'
=> false
>> Time.parse("March 22, 1985, 10:35 PM")
=> 1985-03-22 22:35:00 +0800
epoch (midnight on January 1, 1970, GMT)
创建 date/time 对象
2009-01-02T03:04:05+00:00
=> nil
>> puts DateTime.now
2016-09-12T10:54:22+08:00
=> nil
>> puts DateTime.parse("October 23, 1973, 10:34 AM")
1973-10-23T10:34:00+00:00
=> nil
jd(Julian date),commercial,strptime
date/time 查询方法
=> #
>> dt.year
=> 2016
>> dt.hour
=> 10
>> dt.minute
=> 57
>> dt.second
=> 55
>> t = Time.now
=> 2016-09-12 10:58:12 +0800
>> t.month
=> 9
>> t.sec
=> 12
>> d = Date.today
=> #
>> d.day
=> 12
今天礼拜几?
=> true
>> d.friday?
=> false
date/time 格式化方法
=> 2016-09-12 11:08:22 +0800
>> t.strftime("%y-%m-%d")
=> "16-09-12"
>> t.strftime("%Y-%m-%d")
=> "2016-09-12"
%Y:四位数的年
%y:两位数的年
%b,%B:短月,长月
%m:数字月
%d:日,左带零
%e:日
%a,%A:短日名,长日名
%H,%I:小时,24,12。
%M:分
%S:秒
%c:%a %b %d %H:%M:%S %Y
%x:%m/%d/%y
RFC 2822 (email),RFC 2616(http):
=> "Mon, 12 Sep 2016 00:00:00 +0000"
>> DateTime.now.httpdate
=> "Mon, 12 Sep 2016 03:15:24 GMT"
date/time 转换方法
=> 2016-09-12 11:18:29 +0800
>> t - 20
=> 2016-09-12 11:18:09 +0800
>> t + 20
=> 2016-09-12 11:18:49 +0800
月的转换:
=> #
>> puts dt + 100
2016-12-21T11:19:25+08:00
=> nil
>> puts dt >> 3
2016-12-12T11:19:25+08:00
=> nil
>> puts dt << 10
2015-11-12T11:19:25+08:00
=> nil
天:
=> #
>> puts d.next
2016-09-13
=> nil
>> puts d.next_year
2017-09-12
=> nil
>> puts d.next_month
2016-10-12
=> nil
>> puts d.prev_day(10)
2016-09-02
=> nil
upto,downto:
=> #
>> next_week = d + 7
=> #
>> d.upto(next_week) {|date| puts "#{date} is a #{date.strftime("%A")}"}
2016-09-12 is a Monday
2016-09-13 is a Tuesday
2016-09-14 is a Wednesday
2016-09-15 is a Thursday
2016-09-16 is a Friday
2016-09-17 is a Saturday
2016-09-18 is a Sunday
2016-09-19 is a Monday
=> #
查看帮助:ri Date