[翻译]Ruby教程7——字符串

字符串

在这部分的教程将详细的介绍字符串。


字符串是计算机语言中最重要的数据类型之一,这就是为什么我们决定要用一整章来介绍字符串。


字符串是序列化的unicode字符。它是一种数据类型存储了序列化的值,它的元素通常代表的是根据字符编码的字符。当一个字符串在代码中以字面量出现,它也称为字符串文本。


第一个例子


在Ruby中字符串文本是以单引号或者双引号引起来的。


#!/usr/bin/ruby

# first.rb

puts ‘Python language’
puts “Ruby language”

这个例子有两个字符串,第一个是用单引号,另一个是用双引号。


$ ./first.rb

Python language

Ruby language


程序输出。


使用引号


如果我们想要显示引号该怎么做,直接引用?这有两种方法实现。


#!/usr/bin/ruby

puts “There are many stars”
puts “He said, \”Which one is your favourite?\””

puts ‘There are many stars’
puts ‘He said, “Which one is your favourite?”‘

我们使用()字符将引号转义。通常双引号是用于划定字符串的范围,然后被转义之后它原始的意义就没有了。它在字符串中被作为一个正常的字符。第二种方法是混合使用单引号和双引号。


$ ./quotes.exe

There are many stars.

He said, “Which one is your favourite?”


输出结果。


转义序列


转义符是特殊的字符,在字符串中有特殊的含意。


#!/usr/bin/ruby

puts “one two three four”
puts “one\ntwo\nthree\nfour”

最常用一个的转义符是换行符\n。它在许多编程语言中都有效。换行符之后的字符将出现在新的一行。


$ ./newline.rb

one two three four

one

two

three

four


以上脚本的输出结果中换行符之后的字符在新的一行。




r、b和t是正常的字符,当前面加上\字符后就具有特殊意义了。


#!/usr/bin/ruby

puts “ bbb\raaa”
puts “Joan\b\b\bane”
puts “Towering\tinferno”

这个例子中我们用到了三个不同的转义字符。


puts “   bbb\raaa”

回车符\r控制之后的字符回到行首。之前打印到终端上的字符串会被处理。这个转义字符会将aaa字符位于bbb之前,输出为aaabbb。


puts “Joan\b\b\bane”

\b是退格控制符,它会删掉前一个字符。这个字符串将在终端上打印‘Jane’而不是‘Joan’。


puts “Towering\tinferno”

最后\t转义符是用于两个词之间制表空格的。


$ ./escapes.rb

aaabbb

Jane

Towering inferno


例子的输出结果。




反斜杠\是用于创建转义符的特殊字符。当需要打印反斜杠时,则在它前面加上另一个反斜杠。这意味着转义过了可以打印。在Ruby中单引号和双引号用于划定字符串范围的,想要打印它们同样也需要在前面加上\。


#!/usr/bin/ruby

puts “The special character \“
puts “The special character \’”
puts “The special character \””

这个例子中我们在终端上打印了这三个字符。


$ ./specials.rb

The special character \

The special character ‘

The special character “


输出结果。


访问字符串的元素


在Ruby中我们可以使用方括号[]来访问字符串的元素。在括号内可以使用字符串、范围索引。


#!/usr/bin/ruby

msg = “Ruby language”

puts msg[“Ruby”]
puts msg[“Python”]

puts msg[0]
puts msg[-1]

puts msg[0, 3]
puts msg[0..9]
puts msg[0, msg.length]

这个例子的代码展示了我们可以访问字符串的一部分。


msg = “Ruby language”

这里是我们将要访问的字符串。


puts msg[“Ruby”]

这行代码我们测试字符串‘Ruby’是否是msg的子串。如果是将返回该字符串。


puts msg[0]

可以通过索引来访问这个字符串的字符。编号是从0开始的,也就是说0号索引是第1个字符。msg[0]返回字符串的第一个字符R。


puts msg[-1]

这里我们访问最后一个字符。-1代表了最后一个索引。


puts msg[0, 3]

两个用逗号分隔的索引返回了从第1个索引开始到第2个索引的字符,不包括第2个索引。


puts msg[0..9]

范围操作符也可以完成同样操作。这里我们打印前10个字符。


puts msg[0, msg.length]

这行返回全部的字符。msg.length返回字符串的长度。


$ ./access.rb

Ruby


R

e

Rub

Ruby langu

Ruby language


输出结果。


多行字符串


许多编程语言要创建多行字符串需要额外的努力,在Visual Basic中尤其如此。但是在Ruby中却是很容易。


#!/usr/bin/ruby

puts “I hear Mariachi static on my radio
And the tubes they glow in the dark
And I’m there with her in Ensenada
And I’m here in Echo Park
“

puts %/
Carmelita hold me tighter
I think I’m sinking down
And I’m all strung out on heroin
On the outskirts of town/

puts <<STRING

Well, I’m sittin’ here playing solitaire
With my pearl-handled deck
The county won’t give me no more methadone
And they cut off your welfare check
STRING

这个例子中我们使用了Carmelita歌曲的歌词。我们展示了使用三种方法打印多行字符串。可以使用双引号;可以使用%字符创建多行字符串,用%后面的字符将字符串包围住;最后我们使用定界符,这和语法是使用<<接着一些字符串,用这个字符串包围住多行字符。它必须左对齐。


变量替换


变量替换是将字符串的变量替换成它们的值。为了将变量替换成值,这个变量在字符串需要放在#{和}之间。


#!/usr/bin/ruby

name = “Jane”
age = 17

puts “#{name} is #{age} years old”

这个例子中我们替换了字符串中的两个变量:name和age。


$ ./interpolation.rb

Jane is 17 years old




也可以替换表达式。


#!/usr/bin/ruby

x = 5
y = 6

puts “The product of #{x} and #{y} is #{xy}”

这是一个表达式替换的例子。


$ ./interpolation2.rb

The product of 5 and 6 is 30


运行例子脚本。




这是另一种替换变量的方法。类似于Python 2.x所支持的替换。


#!/usr/bin/ruby

name = “Jane”
age = 17

message = “%s is %d years old” % [name, age]
puts message

以上是一个例子。


message = “%s is %d years old” % [name, age]

使用之前先创建一个字符串。%s和%d是格式化字符,分别表示字符串和数字。值由%字符后面的方括号提供。


字符串连接


字符串连接是从多个字符串创建一个字符串。


#!/usr/bin/ruby

lang = “Ruby” + “ programming” + “ languge”
puts lang

lang = “Python” “ programming” “ language”
puts lang

lang = “Perl” << “ programming” << “ language”
puts lang

lang = “Java”.concat(“ programming”).concat(“ language”)
puts lang

Ruby提供多种方法连接字符串。


lang = “Ruby” + “ programming” + “ languge”

在计算机语言中加法操作符是最常用的一种。Perl和PHP是用的点操作符(.)。


lang = “Python” “ programming” “ language”

Ruby自动连接多个后续的字符串。


lang = “Perl” << “ programming” << “ language”

另一种方法是使用<<操作符。


lang = “Java”.concat(“ programming”).concat(“ language”)

每个字符串字面符实际上都是一个对象。我们可以对Ruby对象调用很多方法。对于字符串对象可以调用concat方法连接两个字符串。它返回最后的结果对象,再对其调用另一个方法。这样我们就将这些方法链接起来了。


$ ./concatenate.rb

Ruby programming languge

Python programming language

Perl programming language

Java programming language


输出结果。


冻结字符串


在Java或者C#中字符串是不可变的,这意味着不能修改已存在的字符串。只能通过已存在的字符串创建一个新的。在Ruby中字符串同样也是不可修改的。


Ruby中字符串对象有一个freeze方法,可以使它们不可变。


#!/usr/bin/ruby

msg = “Jane”
msg << “ is “
msg << “17 years old”

puts msg

msg.freeze

#msg << “and she is pretty”

这个例子我们演示了字符串是可变的。然后在调用freeze方法之后我们就不能再作修改了。如果我们取消掉注释将会得到’can’t modify frozen string’错误信息。


字符串比较


在编程中字符串比较是件平常的事情。我们可以使用==操作符或者eql?方法来比较两个字符串,如果相等返回true,否则false。


#!/usr/bin/ruby

puts “12” == “12”
puts “17” == “9”
puts “aa” == “ab”

puts “Jane”.eql? “Jan”
puts “Jane”.eql? “Jane”

这个例子的代码我们比较了一些字符串。


puts “12” == “12”

这两个是相等的,这行返回true。


puts “aa” == “ab”

第一个字符是相等,然后比较下一个字符。它们不同,因此返回false。


puts “Jane”.eql? “Jan”

eql?方法用于比较两个字符串。所有对象都内建了eql?方法。这个方法将另一个要比较的字符串作为参数传入。


$ ./comparing.rb

true

false

false

false

true


程序输出结果。




Ruby中有一个“飞船(spaceship)”操作符<==>。这个操作符来自Perl,与以上两个比较方法不同,它不是返回true和false,而是返回1、0或者-1。取决于左参数和右参数的关系。如果左参数大于右参数则返回1;如果左参数小于右参数则返回-1;如果相等返回0。什么才是一个字符大于另一个字符呢?字符在表中是有序的,在表中每个字符有一位位置。当比较字符时实际比较它们在表中的位置。例如ASCII表,字符a在b的前面,因此a<==>b返回-1,因为左参数的位置小于右参数b。


#!/usr/bin/ruby

puts “a” <==> “b”
puts “b” <==> “a”
puts “a” <==> “a”

使用“飞船”操作符比较字符串。


$ ./spaceship.rb

-1

1

0


输出结果。




有可能比较字符串不管大小写。在Ruby中有casecmp方法。这个方法与飞船操作符相同。


#!/usr/bin/ruby

puts “Jane”.casecmp “Jane”
puts “Jane”.casecmp “jane”
puts “Jane”.casecmp “Jan”

以上是一个例子。


puts “Jane”.casecmp “Jane”
puts “Jane”.casecmp “jane”

这两行返回结果都是0.因为我们不考虑字符的大小写。


$ ./case.rb

0

0

1


输出结果。


字符串对象


Ruby是面向对象语言。对象是面向对象程序的基本代码块。字符串也是对象。对象由数据和方法组成。在面向对象程序中,创建对象并且相互通信。


#!/usr/bin/ruby

website = “google.com”
puts website

website = String.new “zetcode.com”
puts website

以上例子我们展示了两个创建字符串的基本方法。


website = “google.com”

这里是使用字符串字面量创建了一个website字符串变量。


website = String.new “zetcode.com”

这是标准创建字符串对象的方法。然而第一和更常用,因为它更简洁,并且在计算机语言中更普遍。




#!/usr/bin/ruby

puts “zetcode”.upcase
puts “zetcode”.size
puts “zetcode”.reverse

这个例子中我们对字符串字面量调用了三个方法。如果是熟悉Java或者C的人可能会困惑。在Ruby中调用方法时字符串字面量会转化为一个字符串对象。


$ ./stringobject2.rb

ZETCODE

7

edoctez


输出结果。


字符串方法


Ruby字符串对象有一些有用的方法。如我们见到过的concat或者eql?。


#!/usr/bin/ruby

word = “Determination”

puts “The word #{word} has #{word.size} characters”

puts word.include? “tion”
puts word.include? “tic”

puts

puts word.empty?
word.clear
puts word.empty?

创建一个字符串变量,展示了四个字符串的方法。


puts “The word #{word} has #{word.size} characters”

size方法返回字符串的长度。


puts word.include? “tion”

include?方法判断一个字符串是否为子串。这里返回的是true。


puts word.empty?
word.clear

empty?方法检查字符串是否为空。返回一个布尔值。clear方法清空字符串。


$ ./basicmethods.rb

The word Determination has 13 characters

true

false


false

true


输出结果。




接下来的例子介绍字符串大小写的方法。


#!/usr/bin/ruby

ruby = “Ruby programming language”

puts ruby.upcase
puts ruby.downcase
puts ruby.capitalize
puts ruby.swapcase

Ruby中有四个与大小写相关的方法。upcase方法将字符串全转为大写并返回一个新对象;downcase方法是将字符串全转为小写并返回一个新对象;capitalize方法是将字符串的首字母大写并返回一个新的对象。最后swapcase方法是将大小写反转并返回一个新对象。


$ ./rubylang.rb

RUBY PROGRAMMING LANGUAGE

ruby programming language

Ruby programming language

rUBY PROGRAMMING LANGUAGE


输出结果。




接下来展示两个Ruby字符串的方法:start_with? 和end_with?。这两个方法都是返回布尔值。它们判断一个字符串是否分别以另一个字符串开头或结尾。


#!/usr/bin/ruby

ws1 = “zetcode.com”
ws2 = “www.gnome.org”

puts ws1.start_with? “www.”
puts ws2.start_with? “www.”

puts

puts ws1.end_with? “.com”
puts ws2.end_with? “.com”

这是一个上述方法的例子。


puts ws1.start_with? “www.”

这里检查一个字符串是否以“www.”开头。如果不是则在终端打印false。


puts ws1.end_with? “.com”

检查字符串ws1是否以”.com”结尾。如果是则在终端打印true。


$ ./startend.rb

false

true


true

false


输出结果。




接下来我们介绍inspect方法。这个方法返回被引号包围原始的字符串,对于特殊字符不处理。对于想要检查字符串由哪些字符组成的比较有用。


#!/usr/bin/ruby

msg = “Jane\t17\nThomas\t23”

puts msg
puts msg.inspect

inspect方法的一个例子。


msg = “Jane\t17\nThomas\t23”

这个字符串有一些特殊的字符。


puts msg
puts msg.inspect

第一种情况,字符串中的制表符和换行符被解释了。第二种情况我们得到了一个原始格式的字符串。


$ ./inspectmethod.rb
Jane 17
Thomas 23
“Jane\t17\nThomas\t23”

输出结果。




chomp方法是将字符串尾部的分隔符去掉并返回一个新对象。默认的分隔符是换行符(\n)。


#!/usr/bin/ruby

print “Are you sure to download? (Yes/No) “

response = gets

if (response.downcase == “yes”)
puts “Downloaded”
else
puts “Download cancelled”
end

puts response.inspect

上面的脚本我们从用户输入一些内容,然后再返回给用户。


$ ./chomp.rb

Are you sure to download? (Yes/No) Yes

Download cancelled

“Yes\n”


这个脚本没有正确的工作。原因很清晰,由inspect返回了。用户输入的内容以回车键结尾,因此换行符也被包含其中了。”Yes”与”Yes\n”不相等。要使用脚本正确运行,我们使用chomp方法移除掉换行符。


#!/usr/bin/ruby

print “Are you sure to download? (Yes/No) “

response = gets

if (response.downcase.chomp == “yes”)
puts “Downloaded”
else
puts “Download cancelled”
end

puts response.inspect

这个是正确的脚本。


if (response.downcase.chomp == “yes”)

这里我们在比”Yes”比较之前对输入内容进行了处理。


$ ./chomp.rb

Are you sure to download? (Yes/No) Yes

Downloaded

“Yes\n”


现在脚本正确工作了。


格式化字符串


Ruby中有格式化说明符。格式化说明符决定了如何显示一个字符串。它以%字符开始。格式化说明符放在单引号或者双引号内。


格式化说明符有以下字段。


%[flags][field width][precision]conversion specifier


方括号内的字段是可选的。


转换说明符表明数据将如何进行转换。


#!/usr/bin/ruby

puts “There are %d oranges in the basket.” % 12
puts “There are %d oranges and %d apples in the basket.” % [12, 10]

这是一个格式化说明符的例子。


puts “There are %d oranges in the basket” % 12

当我们在字符串中使用%d,我们在这个位置将期望一个数字。d是十进制数的转换说明符。这个数据在%字符后面给出。


puts “There are %d oranges and %d apples in the basket” % [12, 10]

当我们在一个字符串中使用多个格式化说明符时,每个都以%开始。多个值放在[]之间并以逗号分隔。


$ ./formatspecifiers.rb

There are 12 oranges in the basket.

There are 12 oranges and 10 apples in the basket.


输出结果。




接下来的例子我们介绍一些基本的转换符。


#!/usr/bin/ruby

puts “There are %d apples.” % 5
puts “I can see %i oranges.” % 3
puts “The width of iPhone 3G is %f mm.” % 62.1
puts “This animal is called a %s” % “rhinoceros.”

我们使用了整数、浮点数和字符串的转换符。


puts “There are %d apples.” % 5
puts “I can see %i oranges.” % 3

d和i都是用于整数。


puts “The width of iPhone 3G is %f mm.” % 62.1

f用于浮点数。默认浮点数有6个小数。


puts “This animal is called a %s” % “rhinoceros.”

s用于字符串。


$ ./basicspecifiers.rb

There are 5 apples.

I can see 3 oranges.

The width of iPhone 3G is 62.100000 mm.

This animal is called a rhinoceros.


输出结果。




接下来是一个实践的例子。


#!/usr/bin/ruby

website = “zetcode.com”

website.each_char do |c|
print “#{c} has ASCII code %d\n” % c.ord
end

这个例子我们记遍历字符串的所有字符并在终端上打印它的ASCII值。


website.each_char do |c|
print “#{c} has ASCII code %d\n” % c.ord
end

each_char方法将website字符串中的每个字符传给代码块,一个字符是一次循环。当前的字符保存在这是c中。我们使用ord方法获取字符的ASCII值。


$ ./character.rb

z has ASCII code 122

e has ASCII code 101

t has ASCII code 116

c has ASCII code 99

o has ASCII code 111

d has ASCII code 100

e has ASCII code 101

. has ASCII code 46

c has ASCII code 99

o has ASCII code 111

m has ASCII code 109


输出结果。




数字有多种显示形式。


#!/usr/bin/ruby

# decimal
puts “%d” % 300

# hexadecimal
puts “%x” % 300

# octal
puts “%o” % 300

# binary
puts “%b” % 300

# scientific
puts “%e” % (5/3.0)

上面的例子中我们打印数字的十进制、十六进制、八进制、二进制和科学记数的形式。


# hexadecimal
puts “%x” % 300

x转换符用于将数字转为十六进制格式。


# binary
puts “%b” % 300

b转换符用于将数字转为二进制格式。


$ ./various.rb

300

12c

454

100101100

1.666667e+00


输出结果。




精度是格式化说明符的一个字段。它指明了后面小数点的位数。它对于整数、小数和字符串有不同的意义。当用于整数时表明了最少打印多少个数字。如果数字个数少于精度则前面用0补全。对于整数精度默认为1,表示前面没有0.当用于浮点数时表示小数点后显示多少个数字。最后,用于字符串时精度表示多少个字符会打印。


#!/usr/bin/ruby

puts ‘Height: %f %s’ % [172.3, ‘cm’]
puts ‘Height: %.1f %s’ % [172.3, ‘cm’]

puts “%d” % 16
puts “%.5d” % 16

puts “%s” % “zetcode”
puts “%.5s” % “zetcode”

这个例子中我们使用了精度字段。


puts ‘Height: %f %s’ % [172.3, ‘cm’]
puts ‘Height: %.1f %s’ % [172.3, ‘cm’]

172.3是一个浮点数。如果没有指定精度则会显示6个小数。这里将会显示5个0.第二行的.1是精度,它将小数个数减为1。的


puts “%d” % 16
puts “%.5d” % 16

对于整数默认精度为1。第二行中我们指明了精度为.5,这将会在16前面加上3个0。


puts “%s” % “zetcode”
puts “%.5s” % “zetcode”

第一行会打印所有的字符串。第二行仅打印5个,有两个字符将抛弃。


$ ./precision.rb

Height: 172.300000 cm

Height: 172.3 cm

16

00016

zetcode

zetco


输出结果。




宽度字段表示数据最小要显示的宽度。它是一个数字,并且在小数点之前。如果输出比较短,则会被用空格填充,且右对齐。如果宽度前面有减号则会左对齐。如果输出比宽度长则会完整输出。


#!/usr/bin/ruby

puts “%d” % 1
puts “%d” % 16
puts “%d” % 165
puts “%d” % 1656
puts “%d” % 16567

puts “%10d” % 1
puts “%10d” % 16
puts “%10d” % 165
puts “%10d” % 1656
puts “%10d” % 16567

第一种情况打印5个数字没有指明宽度。输出的宽度即为数字的位数。第二种情况指明宽度为10。则每个都最少输出10字符的长度,数字右对齐。


puts “%d” % 1
puts “%d” % 16

打印两个数字,输出的宽度分别为1、2个字符。


puts “%10d” % 1
puts “%10d” % 16

这里宽度都为10个字符。这两个数被填充了8、9个空格。


$ ./fieldwidth.rb
1
16
165
1656
16567
1
16
165
1656
16567

我们发现第二种情况数字是右对齐的。




标志修饰符修改了模式的行为。


#标志分别在二进制、八进制各十六进制前加上0b、0和0x。它会给小数加上小数点,即使这个小数人被精度限制了。


#!/usr/bin/ruby

puts “%#b” % 231
puts “%#x” % 231
puts “%#o” % 231

puts “%.0e” % 231
puts “%#.0e” % 231

puts “%.0f” % 231
puts “%#.0f” % 231

这个例子我们使用了#标志。


puts “%#b” % 231
puts “%#x” % 231
puts “%#o” % 231

十进制数231分别以二进制、八进制和十六进制打印。#标志会给它们加上前缀。


puts “%.0e” % 231
puts “%#.0e” % 231

这个.0限制了小数个数。然后使用#标志后小数点会显示,即使没有小数值。


$ ./flags1.rb

0xe7

0b11100111

0347

2e+02

2.e+02

231

231.


输出结果。




+标志会给正数加上正号。对于二进制、十六进制和八进制的负数会加上负号并使用它的绝对值。


#!/usr/bin/ruby

puts “%d” % 231
puts “%+d” % 231
puts “%d” % -231
puts “%+d” % -231

puts “%b” % -231
puts “%o” % -231
puts “%x” % -231

puts “%+b” % -231
puts “%+o” % -231
puts “%+x” % -231

一个演示+标志符的例子。


puts “%d” % 231
puts “%+d” % 231

通常正数的符号会被忽略掉。如果想要显示正数的符号可以使用+标志符。


puts “%d” % -231
puts “%+d” % -231

+标志符对负数没有影响,输出结果还是一样的。


puts “%b” % -231
puts “%o” % -231
puts “%x” % -231

二进制、八进制和十六进制的数有它们自己生成负数的方法。


puts “%+b” % -231
puts “%+o” % -231
puts “%+x” % -231

如果我们对负数指定了+标志,我们将数字转为不同的格式并加上负号。没有专门的方式表示负数。


$ ./flags2.rb

231

+231

-231

-231

..100011001

..7431

..f19

-11100111

-347

-e7


输出结果。




这里介绍0标志和-标志。0标志会用0代替空格来填充数字。-标志会将输出左对齐。


#!/usr/bin/ruby

puts “%010d” % 1
puts “%010d” % 16
puts “%010d” % 165
puts “%010d” % 1656
puts “%010d” % 16567

puts “%-10d” % 1
puts “%-10d” % 16
puts “%-10d” % 165
puts “%-10d” % 1656
puts “%-10d” % 16567

以上是一个例子。


puts “%010d” % 1
puts “%010d” % 16

数字会用0填充。


puts “%-10d” % 1
puts “%-10d” % 16

数字个数比宽度短,且会左对齐。


$ ./fieldwidth2.rb

0000000001

0000000016

0000000165

0000001656

0000016567

1

16

165

1656

16567


输出结果。




标志符用于精度和宽度。当我们使用符号时精度和宽度将作为一个参数。


#!/usr/bin/ruby

puts “%.
f” % [3, 1.1111111]
puts “%0d” % [10, 2]
puts “%0
.f” % [10, 3, 1.1111]

使用了标志的的例子。


puts “%.f” % [3, 1.1111111]

这里使用作为精度,则第一个数字3是精度的参数。它只为显示1.1111111的3个小数。


puts “%0d” % [10, 2]

这行的代码我们使用标志作为宽度。我们必须在[]之间加上宽度。第一个数字是宽度,第十个数字是要转换的值。


puts “%0.f” % [10, 3, 1.1111]

*标志可以同时用于宽度和精度。这样我们就必须都在[]中指明。


$ ./flags3.rb

1.111

0000000002

000001.111


输出结果。


这章的教程介绍的Ruby的字符串。




原文地址: http://zetcode.com/lang/rubytutorial/strings/

翻译:龙昌 admin@longchangjin.cn

完整教程:https://github.com/wusuopu/Ruby-tutorial