[翻译]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


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




rbt是正常的字符,当前面加上\字符后就具有特殊意义了。


#!/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”

这个例子中我们替换了字符串中的两个变量:nameage


$ ./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,与以上两个比较方法不同,它不是返回truefalse,而是返回1、0或者-1。取决于左参数和右参数的关系。如果左参数大于右参数则返回1;如果左参数小于右参数则返回-1;如果相等返回0。什么才是一个字符大于另一个字符呢?字符在表中是有序的,在表中每个字符有一位位置。当比较字符时实际比较它们在表中的位置。例如ASCII表,字符ab的前面,因此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

di都是用于整数。


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