如何在Ruby中使用字符串

来自菜鸟教程
跳转至:导航、​搜索

介绍

string 是一个或多个字符的序列,可能由字母、数字或符号组成。

Ruby 中的字符串是对象,与其他语言不同,字符串是 可变的,这意味着它们可以就地更改而不是创建新字符串。

您将在几乎每个编写的程序中使用字符串。 字符串让您可以使用文本显示并与用户交流。 实际上,您现在正在阅读的页面是由通过 Web 浏览器显示在屏幕上的字符串组成的。 字符串是编程最重要的基础之一。

在本教程中,您将学习如何在 Ruby 中使用字符串。 您将创建字符串、将它们显示在屏幕上、将它们存储在变量中、将多个字符串连接在一起,并学习如何处理特殊字符,例如换行符、撇号和双引号。

创建和打印字符串

字符串存在于 Ruby 中的单引号 ' 或双引号 " 中,因此要创建字符串,请将一系列字符包含在其中一个或另一个中:

'This is a string in single quotes.'

"This is a string in double quotes."

您可以选择使用单引号或双引号。 在大多数情况下,您选择哪一个并不重要,只要您保持一致即可。 但是,使用双引号可以让您执行 字符串插值 ,您将在本教程中了解这一点。

要在程序中显示字符串,可以使用 print 方法:

print "Let's print out this string."

print 方法完全按照所写的方式显示字符串。

试试看。 使用文本编辑器创建一个名为 print.rb 的新 Ruby 程序 ,并使用 print 打印三个字符串:

打印.rb

print 'This is the first string.'
print 'This is the second string.'
print 'This is the third string.'

保存文件并运行程序:

ruby print.rb

您将看到以下输出:

OutputThis is the first string.This is the second string.This is the third string.

不是将三个字符串打印在各自的行上,而是将所有三个字符串一起打印在一行上。 print 方法将字符串打印到屏幕上,但是如果您希望每个字符串单独一行,您必须自己添加一个换行符。

如果您想将所有三个字符串放在不同的行上,请改用 puts 方法。 修改您的程序以使用 puts 而不是 print

打印.rb

puts 'This is the first string.'
puts 'This is the second string.'
puts 'This is the third string.'

现在再次运行程序,您将看到以下输出:

OutputThis is the first string.
This is the second string.
This is the third string.

puts 方法打印您指定的字符串,但还会为您在字符串的末尾添加一个换行符。

将字符串存储在变量中

Variables 是对计算机内存中某个位置的命名引用。 您使用变量来存储数据并在以后检索它。

要将字符串存储在变量中,请定义变量名称并分配字符串的值:

my_string = 'This is my string'

然后,要检索值,请使用变量的名称:

print my_string

要自己测试一下,请在编辑器中创建文件 string_variables.rb 并添加以下代码:

string_variables.rb

my_name = "Sammy the Shark"
my_age = "none of your business"

puts my_name
puts my_age

该程序定义了两个变量:my_name 和 my_age。 每个变量都分配有一个字符串。 然后我们使用 puts 方法将每个字符串打印在自己的行上。

保存文件并执行程序:

ruby string_variables.rb

您将看到以下输出:

OutputSammy the Shark
none of your business

通过将字符串分配给变量,您可以避免每次要使用相同的字符串时一遍又一遍地键入,从而更容易在程序中使用和操作字符串。

让我们看看如何将字符串连接在一起以创建新字符串。

字符串连接

Concatenation 表示将两个或多个字符串连接在一起以创建一个新字符串。 为了连接,我们使用连接运算符,由 + 符号表示。 当与算术运算一起使用时,+ 符号也是加法运算符。

以下是将字符串 sammyshark 连接在一起的方法:

"sammy" + "shark"

这将产生以下输出:

Outputsammyshark

串联将字符串首尾相连,将它们组合起来并输出一个全新的字符串值。 如果你想在单词 sammyshark 之间有一个空格,则必须在其中一个字符串中包含该空格,如下所示:

"sammy " + "shark"

现在,您不会真正在程序中编写这样的代码,但是您需要经常将字符串和变量混合在一起,这就是串联的用武之地。

这是一个例子:

color = "Blue"
print "My favorite color is " + color

这将导致输出 My favorite color is blue。 请注意,我们在字符串中的单词 is 之后留下了一个空格,因此输出将在字符串和输出中的变量值之间有一个空格。

您可以通过这种方式将多个字符串连接在一起。 创建文件 concatenation.rb 并添加以下代码:

连接.rb

my_name = "Sammy the Shark"
my_age = "none of your business"

puts "My name is " + my_name + " and my age is " + my_age + "."

该程序定义了两个变量:my_namemy_string,每个变量都有自己分配的字符串,就像您之前所做的那样。 但这一次,我们不是打印值,而是打印一个字符串,该字符串使用连接来打印具有更多上下文的值。

运行此程序时,您将看到以下输出:

OutputMy name is Sammy the Shark and my age is none of your business.

在这个小程序中,您使用连接将变量插入到该字符串中。

当您通过连接组合两个或多个字符串时,您正在创建一个可以在整个程序中使用的新字符串,因此您可能希望将创建的字符串分配给一个新变量,以便以后使用:

连接.rb

my_name = "Sammy the Shark"
my_age = "none of your business"

# assign concatenated string to variable
output = "My name is " + my_name + " and my age is " + my_age + "."

# Print the output.
puts output

在这样的小程序中,可能不需要使用额外的 output 变量。 但是在较大的程序中,您可能希望使用将在多个地方使用的连接来创建一个字符串。 将数据处理(如连接和算术)与输出分开也是一个好习惯,因为最终您的程序会变得更大,并且您希望将逻辑和输出分开到单独的文件或组件中,以使它们更易于管理。

确保不要在两种不同的数据类型之间使用 + 运算符。 例如,您不能将字符串和整数连接在一起。

要查看会发生什么,请创建一个名为 strings_and_integers.rb 的新程序,其内容如下:

字符串和整数.rb

my_name = "Sammy the Shark"
my_number = 27

print my_name + my_number

这次我们有 my_name 保存字符串 Sammy the Sharkmy_number 保存整数 27。 我们知道 27 不是字符串,因为它被引号包围。 它也没有小数点,所以我们知道它是一个整数。

如果你运行程序:

ruby strings_and_ints.rb

您将看到以下错误消息:

Outputstrings_and_ints.rb:4:in `+': no implicit conversion of Integer into String (TypeError)
    from strings_and_ints.rb:4:in `<main>'

错误 no implicit conversion of Integer into String 意味着 Ruby 只能将字符串连接到现有字符串。

在 Ruby 2.3 及更低版本中,您会看到以下错误消息:

strings_and_ints.rb:4:in `+': no implicit conversion of Fixnum into String (TypeError)
    from strings_and_ints.rb:4:in `<main>'

关键字 Fixnum 是 Ruby 早期版本中赋予整数的数据类型。 它是固定数字的缩写。 在 Ruby 2.4 中,Fixnum 及其对应的 Bignum 不再存在,而是被 Integer 取代。


我们可以修改我们的程序并将数字27 放在引号中("27"),以便将其声明为字符串而不是整数。 或者我们可以在创建字符串时将数字转换为字符串,如下所示:

字符串和整数.rb

my_name = "Sammy the Shark"
my_number = 27

print my_name + my_number.to_s

.to_s 方法将整数转换为字符串。 这是一种更好的方法,因为它可以让我们在程序中将数字保持为整数。 当我们打印出来时,我们只需要它是一个字符串,但如果我们必须在程序逻辑的其他部分使用它,我们可能希望它是一个整数。

再次运行程序,您将看到 Sammy the Shark27 打印到屏幕上。

在处理邮政编码、货币、电话号码和其他要在屏幕上与文本一起显示的数字数据时,您会经常遇到将数字转换为字符串以进行连接的事情。

串联很强大,但也可能很棘手。 如果您不小心遗漏了 + 运算符之一,您可能会遇到语法错误。 如果必须将字符串与保存数字的变量连接起来,则必须将变量转换为字符串。 Ruby 提供了另一种将变量值注入字符串的方法,称为 字符串插值 ,它解决了这两个问题。

使用字符串插值

连接字符串和变量时,输出可能难以阅读和调试。 字符串插值通过让您将表达式嵌入用双引号括起来的字符串中来解决这个问题。

而不是这样写:

"My name is " + my_name + "!"

你可以这样做:

"My name is #{my_name}!"

不是终止字符串并使用 + 运算符,而是使用 #{} 语法将变量括起来。 此语法告诉 Ruby 计算表达式并将其注入到字符串中。

试试看。 创建一个名为 interpolation.rb 的新程序并添加以下代码:

插值.rb

my_name = "Sammy the Shark"
my_age = "none of your business"

output = "My name is #{my_name} and my age is #{my_age}."

puts output

这是您已经编写的同一个程序,但这次我们使用字符串插值来创建输出。

字符串插值还有一个好处:它可以自动将数值转换为字符串。 还记得你的 strings_and_integers.rb 程序吗? 再次在编辑器中打开该文件,但更改最后一行,使其如下所示:

字符串和整数.rb

my_name = "Sammy the Shark"
my_number = 27

# use interpolation instead of concatenation
print "My name is #{my_name} and my favorite number is #{my_number}."

Ruby 会自动将 my_number 转换为字符串,您的程序将在运行时打印以下输出:

OutputMy name is Sammy the Shark and my favorite number is 27.

字符串插值功能强大且方便。 它也是连接字符串和变量的首选方法。

字符串文字和字符串值

请注意,您创建的所有字符串都包含在代码中的引号中,但实际打印输出不包括引号。

提及这些中的每一个时都有区别。 string literal 是写在源代码中的字符串,包括引号。 字符串值 是您在输出中看到的,不包括引号。

这是一个字符串文字:

"Sammy the Shark"

字符串值为 Sammy the Shark

在大多数情况下,您不必担心这种差异,除非您想在字符串中使用引号或撇号等特殊字符。

转义字符串中的引号和撇号

由于引号用于表示字符串,因此如果您想要在字符串中使用撇号和引号,则必须做一些额外的工作。

如果您尝试在单引号字符串的中间使用撇号,如下所示:

'This isn't what I wanted.'

isn't 中的撇号结束了字符串,从这个例子中奇怪的突出显示可以看出。 因此,Ruby 解释器将尝试将预期的字符串的其余部分解析为代码,您将收到错误消息。

如果您在用双引号括起来的字符串中使用双引号,您会遇到同样的情况:

"Sammy says, "Hello!""

在这个例子中,Hello 前面的右双引号终止了字符串,Hello! 之后的双引号创建了一个没有匹配双引号的新字符串来终止它,所以Ruby 将显示错误。

为避免此问题,您有几个选择。 首先,您可以使用替代语法来创建字符串; 如果必须在字符串中使用双引号,请使用单引号定义字符串,反之亦然。 您也可以 escape 引号,或者您可以使用不同的 Ruby 语法来定义字符串。 让我们看看每种方法。

选项 1:使用备用字符串语法

解决这些问题的最简单方法是在字符串需要包含双引号时将字符串括在单引号中,并在字符串需要使用单引号时将字符串括在双引号中。

而不是用单引号定义这个字符串:

'This isn't what I wanted.'

用双引号定义它:

"This isn't what I wanted."

而不是使用双引号来定义这个字符串:

"Sammy says, "Hello!""

使用单引号:

'Sammy says, "Hello!"'

使用替代语法可以让你摆脱一些快速的堵塞,但它并不总是能奏效。 例如,这两种方法都不适用于此字符串:

"Sammy says, "I'm a happy shark!""

在这个例子中,I'm 前面的结束双引号真的把事情搞砸了。 这会终止第一个字符串,然后 Ruby 在 I'm 中遇到撇号,这会启动一个值为 m a happy shark!"" 的新字符串。 但是这个新字符串没有匹配的单引号来终止它。 并且使用单引号将字符串括起来会引入类似的问题:

'Sammy says, "I'm a happy shark!"'

这次 I'm 中的撇号终止了字符串。

使用替代语法也会使您的代码不一致。 不断在字符串语法之间切换会让人感到困惑,我们可以转义字符来解决这个问题。

选项 2:转义字符串中的字符

反斜杠字符 (\) ,通常称为字符串中的 转义字符 ,它将阻止 Ruby 从字面上解释字符串中的下一个字符。

这是我们有问题的字符串,用双引号编码,里面有双引号:

"Sammy says, "I'm a happy shark!""

创建一个名为 quoting.rb 的新 Ruby 程序并将此代码添加到文件中:

引用.rb

print "Sammy says, "I'm a happy shark!""

运行程序:

ruby quoting.rb

你会看到这个输出:

Outputquoting.rb:1: syntax error, unexpected tCONSTANT, expecting end-of-input
print "Sammy says, "I'm a happy shark!""
                     ^

要修复错误,请在内部双引号前使用反斜杠:

引用.rb

print "Sammy says, \"I'm a happy shark!\""

然后再次运行程序,你会看到你期望的输出:

Sammy says, "I'm a happy shark!"

请注意,您不必在此示例中转义撇号,因为没有冲突。 您只需要转义会混淆 Ruby 的引号。

您可以通过使用不同的语法来定义字符串来完全避免转义引号。

选项 3:对字符串使用替代语法

到目前为止,您已经使用引号来定义字符串的边界。 您也可以使用其他字符在 Ruby 中创建字符串 您可以定义 分隔符 或您想用来包含字符串的字符,方法是在百分号后指定它,如下所示:

%$Sammy says, "I'm a happy shark!"$

此语法将自动为您转义嵌入的字符串。 实际的字符串如下所示:

"Sammy says, \"I'm a happy shark!\""

但是,更改分隔符意味着您必须在需要使用分隔符时对其进行转义。 在这种情况下。 如果您必须在字符串中使用美元符号,则需要转义字符串中的文字美元符号。

为避免这种情况,您还可以使用成对的大括号、方括号或圆括号作为分隔符。 花括号最常见:

%{Sammy says, "I'm a happy shark!"}

如果需要,这些形式都支持字符串插值。

droplets = 5
print %{Sammy says, "I just created #{droplets} droplets!"}

您还将看到 %Q{}%q{} 用于在 Ruby 程序中定义字符串。 %Q{} 语法与双引号字符串完全一样,这意味着您不必逃避双引号,您将能够使用字符串插值:

droplets = 5
print %Q{Sammy says, "I just created #{droplets} droplets!"}

%q{} 语法的工作方式与单引号字符串完全相同:

%q{Sammy says, "I'm a happy shark!"}

在某些程序中,您可能会看到 %q%Q 语法与括号或方括号一起使用,而不是花括号。

如您所见,有很多方法可以在 Ruby 中创建字符串。 无论您选择哪种方法,请在您的代码中保持一致。 您会发现 %Q{}%{} 方法是最常见的。

现在您知道如何处理特殊字符了,让我们看看如何处理长字符串和换行符。

长字符串和换行符

有时您可能希望在字符串中插入换行符或回车符。 您可以使用 \n\r 转义字符在代码中插入换行符:

output = "This is\na string\nwith newlines"
puts output

该程序将产生以下输出:

OutputThis is
a string
with newlines

从技术上讲,这可以使我们的输出多行。 但是,在一行上写一个很长的字符串很快就会变得非常难以阅读和使用。 有几个解决方案。

首先,您可以使用连接运算符将字符串拆分为多行:

output = "This is a\n" +
         "longer string\n" +
         "with newlines."
puts output

这只是将三个字符串连接在一起,类似于您已经完成的操作。

您也可以将换行符放在字符串中:

output = "This is a
         longer string
         with newlines"
puts output

您还可以使用任何备用字符串语法来创建多行字符串:

output = %{This is a
           longer string
           with newlines}
puts output

在这两个示例中,请注意我们不需要换行符 (\n) 字符。 这种方法保留了空格,包括缩进和换行符。

结果,输出将包含换行符以及所有前导缩进,如下所示:

OutputThis is a
           longer string
           with newlines

为防止这种情况,请从代码中删除多余的空格:

output = %{This is a
longer string
with newlines
}

您还可以使用 heredoc 或“here document”创建多行字符串,该术语用于程序中的多行字符串文字。 以下是您编写该代码的方式:

output = <<-END
This is a
longer string
with newlines
END

<<-ENDEND 标记表示 heredoc 的开始和结束。

Ruby 中的 Heredocs 还保留空白字符,这意味着如果您缩进 heredoc 中的代码,也会保留前导缩进。 所以这段代码:

output = <<-END
  This is a
  longer string
  with newlines
END

会打印出两个缩进空格。

Ruby 2.3 和更高版本提供了“squiggly heredoc”语法,它会自动删除这个前导空格。 将 heredoc 定义中的连字符替换为波浪号,因此 <<- 变为 <<~,如下所示:

output = <<~END
  This is a
  longer string
  with newlines
  and the code is indented
  but the output is not.
END

这会产生以下输出:

OutputThis is a
longer string
with newlines
and the code is indented
but the output is not.

这使您可以使用 heredocs 并保持您的代码很好地缩进。

Ruby 中的 Heredocs 也支持字符串插值。

如您所见,在 Ruby 中有很多方法可以处理换行符和多行字符串。 当您使用现有的 Ruby 代码时,您会遇到所有这些方法,因为每个项目往往都有自己的风格。 在您自己的代码中,选择适合您的样式并保持一致。

字符串复制

有时您可能需要使用 Ruby 多次重复一个字符串。 您可以使用 * 运算符来执行此操作。 与 + 运算符一样,* 运算符与数字一起使用时有不同的用途,它是乘法运算符。 当与一个字符串和一个整数一起使用时,*字符串复制运算符 ,可以重复单个字符串,但您希望使用您提供的整数多次。

要打印出 Sammy 九次,您可以使用以下代码:

print "Sammy" * 9

此代码产生以下输出:

OutputSammySammySammySammySammySammySammySammySammy

您可以使用它来创建一些漂亮的 ASCII 艺术。 创建一个名为 banner.rb 的文件并添加以下代码:

puts "=" * 15
puts "| Hello World |"
puts "=" * 15

你能想象一下程序在运行之前会产生什么吗?

它产生这个输出:

Output===============
| Hello World |
===============

这只是一个小例子,说明如何让计算机为您执行重复性任务。

结论

在本教程中,您学习了如何在 Ruby 编程语言中使用 String 数据类型。 您创建了新字符串,将它们与其他字符串连接起来,并处理了换行符、引号和撇号。 然后,您使用字符串插值来更轻松地混合字符串和变量值,并学习了如何重复字符串。