String字符串
字符串由String类提供,除了直接使用单双引号或其它字面量创建字符串,也可以使用String.new()方法来创建。
a = "hello"
b = String.new("world")
Ruby中的字符串是可变对象。
字符串的连接
直接连接即可:
>> "a""b"
=> "ab"
>> "a" "b"
=> "ab"
>> "a" "b"
=> "ab"
单双引号
这和Perl一样,和Shell也类似。单引号是强引用,双引号是弱引用。
双引号的一个特性是支持表达式、变量内插,使用#符号即可。在Ruby中,#
前缀可以看作是一种对某对象的引用、调用之义。例如:
- 内插全局变量
#$var
- 内插实例变量
#@var
- 内插类变量
#@@var
- 但是对于普通的不带前缀符号的局部变量或表达式,为了避免歧义,通常在
#
后加上{}
。例如#{name}
、#{3+4}
、#{func("hello")}
所以,在双引号中如果#
字符后面的是$ @ @@ {
,需要对#
转义,其它时候,不需要对它转义。
格式化字符串内插
Ruby显然也是支持printf、sprintf的,但是Ruby除了表达式或变量内插,还支持格式化字符串内插。
sprintf "pi is about %.4f",Math::PI
=> "pi is about 3.1416"
"pi is about %.4f" % Math::PI # 单个格式化字符串
=> "pi is about 3.1416"
"%s: %f" % ["pi", Math::PI] # 多个格式化字符串
=> "pi: 3.141593"
"xiaomage = %{age}" % {:age => "23"}
=> "xiaomage = 23"
正如上面的示例,需要进行格式化的字符使用%
标识,并使用%
连接字符串和待替换的值。如果要内插多个字符串,则值部分使用中括号包围(即放进数组)或放进hash。
%q和%Q和%
这和Perl里的q() qq()
是一样的,也是分别充当单引号、双引号的角色。%q()
被解析成单引号,单个%
或%Q
被解析成双引号。
%q %Q
后面的()
是引号的起始、终止定界符,定界符可以替换成其他成对或相同的符号。例如,下面是等价的:
# 以下等价,内部的单引号不需要反斜线转义
%q(hello'world)
%q[hello'world]
%q{hello'world}
%q!hello'world!
%q#hello'world#
# 以下等价
%Q(hello'world)
%Q[hello'world]
%{hello'world} # 单个%是一样的
%!hello'world!
%#hello'world#
如果使用的是成对的定界符,那么在定界符内只要合理的配对,就可以包含定界符字面符号。例如:
%Q(hello(hello world)world)
%<<book>Ruby</book>>
%((1+(2*3)) = #{(1+(2*3))})
%(A mismatched paren \( must be escaped) # 不配对的括号需要转义
关于字符串的可变性
对于Ruby来说,字符串是可变的。所以,无法使用单个对象来引用内容相同的两个字符串,如果能引用的话,其中一个修改了就表示另一个字符串也会修改,但这已经表示同一个对象了。
所以,只要Ruby遇到一个字符串,都会新创建一个字符串对象。这意味着,如果在一个循环中使用了字符串常量,那么这个常量字符串对象也会在每次循环过程中新创建,而这是可以避免的消耗性能的一种方式。
>> 10.times {puts "test".object_id}
12046480
12046340
12046280
12046220
12046160
12046080
12046000
12045880
12045780
12045680
单字符
使用一个问号作为下一个字符的前缀,这个字符将称为字符字面量。例如:
?A # 代表一个大写字母A
?? # 代表一个问号
?" # 代表一个双引号
在Ruby1.8及之前的版本,这是一个单字符序列,会转换成ASCII码存放,在Ruby 1.9之后,单字符等价于只有一个字符的字符串。
>> ?A == 'A'
=> true
扩展字符串:+ * <<
想要连接两个字符串,直接不使用任何连接符或使用"+"就可以。但注意,它们不会自动将其它类型转换成字符串类型,需要手动调用to_s方法来转换。
>> "A""B"
=> "AB"
>> "A"+"B"
=> "AB"
>> "A"2 # SyntaxError:
>> "A"+2 # TypeError
>> "A"+2.to_s
=> "A2"
可使用"<<"将多个字符串追加到某个字符串的尾部,它同样不会自动转换成字符串。这时候字符串就像是一个字符数组一样,但需要知道,Ruby字符串不是字符数组,只是实现了一些好用的操作字符串的方法:
>> "abc" << "hello" <<"world"
=> "abchelloworld"
<<
可以直接追加整数,整数被当作ASCII或其它编码字符进行转换,使得追加到字符串里的是字符。
>> "xyz" << 65
=> "xyzA"
只是需要注意的是,使用+
或直接相连扩展字符串的方式时会自动创建一个新的字符串对象,原始字符串不变,也就是说在得到扩展的结果前拷贝了一些数据进行创建新字符串对象。而使用<<
的方式,因为修改的是字符数组,所以是原地修改的。
>> a="xyz"
=> "xyz"
>> a + "XYZ"
=> "xyzXYZ"
>> a # a没有变
=> "xyz"
>> a << "XYZ"
=&g