Peanut's Book Shelf » 日志 » Why Ruby amazes me? PRuby Chap 5 标准类型
Why Ruby amazes me? PRuby Chap 5 标准类型
Gem Gatherer 发表于 2008-05-02 01:03:14
所有的数字也是对象。可以对各种形式的消息做出响应.
整数也支持几种有用的迭代器。
3.times { print "X" }
1.upto(5) { |i| print i, " "}
9.downto(7) { |i| print i, " "}
50.step(80,5) { |i| print i, " "}
** 注意,只包含数字的字符串在表达式运算时不会被自动转换成数字
<-- "34" + "56"
--> "3456"
** 但是可以这样
<-- Integer("34") + Integer("56")
--> 90
** Ruby的字符串是8比特字节的序列
可以用#{expr}序列把任何ruby代码的表达式放进字符串中
<-- "#{'Ho!'*3}, Mike"
--> "Ho!Ho!Ho!, Mike"
** 甚至可以将一句或多条语句加入#{}
puts "now is #{def the(a)
'the ' + a
end
the('Time')
} for me."
其它构建字符串的方式...
%q : 代表单引号引起的字符串(%q就相当于一个')
%Q : 代表单引号引起的字符串(%Q就相当于一个")
%q/general single-quoted string/ --> 'general single-quoted string'
%Q!general single-quoted string! --> "general double-quoted string"
** %q和%Q后面的第一个字符是分界符。此字符串直到下一个分界符出现为止(不包括分界符本身)
String的一些方法
String#split将一个字符串分割开来,可以接受正则表达式
<-- "1 | 2".split(/\s*\|\s*/)
--> ["1", "2"]
String#chomp将字符串前后的空格去掉
String.squeeze将字符串中重复并连续的字符合并。
<-- "Heeeeeeello world".squeeze("e")
--> "Hello world" # 如果不带参数则unique所有字符
** 有一些函数,例如squeeze,会返回处理后的字符串,但它还有一个版本squeeze!,是在字符串本身上做修改
String#scan可以从字符串中抽取匹配正则表达式的元素
<-- "112|2223".scan(/\d+/)
--> ["112", "2223"]
区间 : Ruby用区间实现了序列(sequence),条件(conditions)和间隔(intervals)
区间作为序列:序列是有起点和终点,并可以在序列中产生连续值的方法
** 序列可以用..和...来产生 ..创建闭区间(包括右端点),而...是开区间(不包括右端点)
1..10
'a'..'z'
** 序列可以用to_a方法转换成列表
<-- (1..3).to_a
--> [1, 2, 3]
<-- ('bar'..'bat').to_a
--> ["bar", "bas", "bat"] #没做任何额外声明就产生这结果了。。。真够智能的-_-
区间的一些方法
<-- d = 0..9
--> true
<-- d.include?(5)
--> 0
<-- [d.min, d.max]
--> [0, 9]
<-- d.reject { |i| i < 5}
--> [5, 6, 7, 8, 9]
** 可以用自己的对象来创建区间,但必须满足两个条件
1. 这些对象可以用<=> (spaceship操作符)来比较大小
class a
def <=>(other)
self.val <=> other.val
end
end
2. 要能用succ产生下一个值
class a
def succ
raise(IndexError, "Too Large") if @val >= 9
a.new(@val.succ)
end
end
这样a就可以作为区间了
as = a.new(2)..a.new(8)
区间作为条件
while line = gets
puts line if line=~/start/ .. line=~/end/
end
这段代码打印从标准输出得到的若干行的集合,每个集合都满足以下条件
1. 集合第一行包含"start"
2. 集合最后一行包含"end"
区间作为间隔
** 可以用===来测试一些值是否落入区间表达式的间隔内
<-- (1..10) === 3.14
--> true
正则表达式:Ruby内建支持。
创建的方式有三种,都是等效的:
a = Regexp.new('/^\s*[a-z]')
b = /^\s*[a-z]'/
c = %r{'/^\s*[a-z]'}
匹配的方式有两种, Regexo#match(string)或者=~(肯定匹配),!~(否定匹配)
name = "Fats Waller"
<-- name =~ /a/
--> 1
** 匹配返回匹配繁盛的字符位置
** 匹配会设置一些ruby线程变量
*** $& 得到与模式匹配的字符串
*** $` 得到匹配之前的字符串
*** $' 得到匹配之后的字符串
*** $~ MatchData对象,后有详述
*** - , 后有详述
** ^和$分别匹配行首和行尾
<-- "a op b" =~ /^op/
--> nil
** \A匹配字符串开头
** \z匹配字符串结尾。若字符串结尾为\n,则会无视\n
** \Z匹配字符串结尾。不会无视\n
** \b匹配词的边界 (组词字符是字母,数字和下划线的任意组合)
** \B匹配非词的边界
[]可以匹配在其之间的任何字符
** 特殊字符.|()[{+^$*?在方括号内被视为普通字符
** 字符串替换仍正常进行,例如\b代表回退空格,\n代表换行
** []内可以使用Posix字符类
字符类
实际内容
含义
\d
[0-9]
数字
\D
[^0-9]
非数字
\s
[ \t\r\n\f]
空格
\S
[^ \t\r\n\f]
非空格
\w
[A-Za-z0-9_]
组词字符
\W
[^A-Za-z0-9_]
非组词字符
| 字符类 | 含义 |
| [:alnum:] | 字母和数字 |
| [:alpha:] | 字母(大小写) |
| [:blank:] | 空格和制表符 |
| [:cntrl:] | 控制字符(至少包括0x00-0x1f,0x7f) |
| [:digit:] | 数字 |
| [:graph:] | 除了空格之外的可打印字符 |
| [:lower:] | 小写字母 |
| [:print:] | 任何可打印字符 |
| [:punct:] | 除字母数字和空格外的可打印字符 |
| [:space:] | 空格 |
| [:upper:] | 大写字符 |
| [:xdigit:] | 16进制数字(0-9,a-f,A-F) |
重复: 若r代表任何模式,那么
r* 代表0或多个
r+ 代表1或多个
r? 代表0或1个
** r*和r+的匹配都是贪心的
编组收集:小括号在正则表达式中有重要的作用
<-- show_regexp('banana', /(an)*/)
--> <<banana>>
括号的作用一是改变优先级,二是收集括号匹配的结果。
Ruby计算开始括号的数目,保存每个开始括号和相应的关闭括号之间部分匹配的结果。可以在模式的剩余部分和Ruby程序中使用这种部分匹配
** 在模式内部,指的是第一个组的匹配,是第二个,...
** 在模式外,则有,等特殊变量。
** 这可以让你轻易寻找各式各样的重复,例如
<-- show_regexp("Mississippi", /(\w+)/)
--> M<<ississ>>ippi
基于模式的替换
String#sub替换一次,而String#gsub对所有满足的子串都加以替换
** 函数的第一个参数是正则表达式,第二个参数可以是String或者Block。如果是block,匹配的子串会传递给block,block的结果会替换到原先的子串中
MatchData对象
** 每次调用Regexp#match时候,如果失败则返回nil,如果成功,返回MatchData类的一个实例。MatchData对象让你访问关于这次匹配的所有可用信息。
MatchData ma;
ma[0] ---> $&
ma[1]..ma[9] ---> ..
ma.pre_match ---> $`
ma.post_match ---> $'
