跳到内容

Ruby 编程/语法/字面量

来自 Wikibooks,开放的书籍,开放的世界
123                       # Fixnum
-123                      # Fixnum (signed)
1_123                     # Fixnum (underscore is ignored)
-543                      # Negative Fixnum
123_456_789_123_456_789   # Bignum
123.45                    # Float
1.2e-3                    # Float
123.45r                   # Rational, introduced in ruby 2.1
0xaabb                    # (Hexadecimal) Fixnum
0377                      # (Octal) Fixnum
-0b1010                   # (Binary [negated]) Fixnum
0b001_001                 # (Binary) Fixnum
?a                        # ASCII character code for 'a' (97)
?\C-a                     # Control-a (1)
?\M-a                     # Meta-a (225)
?\M-\C-a                  # Meta-Control-a (129)

注意:"?x" 符号的含义已更改。在 ruby 1.9 中,它不再表示 ASCII 数值代码,而是一个字符串,例如 ?a == "a"

字符串

[编辑 | 编辑源代码]

示例

"this is a string"
=> "this is a string"

"three plus three is #{3+3}"
=> "three plus three is 6" 

foobar = "blah"
"the value of foobar is #{foobar}"
=> "the value of foobar is blah" 

'the value of foobar is #{foobar}'
=> "the value of foobar is \#{foobar}"

字符串表达式以双引号或单引号开头和结尾。双引号字符串表达式会进行反斜杠符号和插值。单引号字符串表达式不会进行插值,但会对 \' 和 \\ 进行处理。

反斜杠符号

[编辑 | 编辑源代码]

也称为转义字符转义序列,它们用于在字符串中插入特殊字符。

示例

"this is a\ntwo line string"
"this string has \"quotes\" in it"
转义序列 含义
\n 换行符 (0x0a)
\s 空格 (0x20)
\r 回车符 (0x0d)
\t 制表符 (0x09)
\v 垂直制表符 (0x0b)
\f 换页符 (0x0c)
\b 退格符 (0x08)
\a 响铃/警报 (0x07)
\e 转义 (0x1b)
\nnn 八进制值为 nnn 的字符
\xnn 十六进制值为 nn 的字符
\unnnn Unicode 代码点 U+nnnn(Ruby 1.9 及更高版本)
\u{nnnnn} 超过四个十六进制数字的 Unicode 代码点 U+nnnnn 必须用花括号括起来
\cx 控制-x
\C-x 控制-x
\M-x meta-x
\M-\C-x meta-control-x
\x 字符 x 本身(例如 "" 是双引号字符)

对于十进制值的字符,您可以执行以下操作

"" << 197 # 将十进制值 197 添加到字符串中

=> Å

或将它们嵌入,如下所示

"#{197.chr}"

插值允许 Ruby 代码出现在字符串中。评估该代码的结果将插入到字符串中

 "1 + 2 = #{1 + 2}"    # => "1 + 2 = 3"
 #{expression}

表达式可以是几乎任何 Ruby 代码。Ruby 在处理字符串分隔符方面非常聪明,它通常会按照您的意愿进行操作。代码将与它在字符串外部产生的副作用相同,包括任何错误

"the meaning of life is #{1/0}"
=> divided by 0 (ZeroDivisionError)

The % 符号

[编辑 | 编辑源代码]

还有一种受 Perl 启发的引用字符串方法:使用 %(百分号)并指定一个分隔符,例如

%{78% of statistics are "made up" on the spot}
=> "78% of statistics are \"made up\" on the spot"

任何非字母数字字符都可以用作分隔符,%[包括这些], %?或这些?, %~或甚至这些东西~。通过使用这种符号,通常的字符串分隔符 " 和 ' 可以出现在字符串中,无需转义,但当然您选择的新的分隔符需要转义。但是,如果您使用 %(括号), %[方括号), %{花括号}%<尖括号> 作为分隔符,则只要它们处于平衡对中,这些相同的分隔符就可以不转义地出现在字符串中

%(string (syntax) is pretty flexible)
=> "string (syntax) is pretty flexible"

修饰符字符可以出现在 % 之后,例如 %q[]、%Q[]、%x[] - 这些决定如何插值字符串以及生成什么类型的对象

修饰符 含义
%q[ ] 非插值字符串(除了 \\\[\]
%Q[ ] 插值字符串(默认)
%r[ ] 插值正则表达式(标志可以出现在结束分隔符之后)
%i[ ] 非插值符号数组,用空格分隔(Ruby 2.0 之后)
%I[ ] 插值符号数组,用空格分隔(Ruby 2.0 之后)
%w[ ] 非插值单词数组,用空格分隔
%W[ ] 插值单词数组,用空格分隔
%x[ ] 插值 shell 命令
%s[ ] 非插值符号

以下是一些更多示例

%Q{one\ntwo\n#{ 1 + 2 }}
=> "one\ntwo\n3"

%q{one\ntwo\n#{ 1 + 2 }}
=> "one\\ntwo\\n#{ 1 + 2 }"

%r/#{name}/i
=> /nemo/i

%w{one two three}
=> ["one", "two", "three"]

%i{one two three} # after Ruby 2.0
=> [:one, :two, :three]

%x{ruby --copyright}
=> "ruby - Copyright (C) 1993-2009 Yukihiro Matsumoto\n"

"Here document" 符号

[编辑 | 编辑源代码]

还有一种创建字符串的方法,称为“here document”,其中分隔符本身可以是任何字符串

string = <<END
on the one ton temple bell
a moon-moth, folded into sleep,
sits still.
END

语法以 << 开头,后面紧跟着分隔符。要结束字符串,分隔符单独出现在一行上。

有一种更简洁的写法,可以使结束分隔符缩进空白

string = <<-FIN
           on the one-ton temple bell
           a moon-moth, folded into sleep
           sits still.

           --Taniguchi Buson, 18th century; translated by X. J. Kennedy
         FIN

要使用分隔符中的非字母数字字符,可以对它进行引用

string = <<-"."
           Orchid - breathing
           incense into
           butterfly's wings.

           --Matsuo Basho; translated by Lucien Stryk
         .

Here document 是插值的,除非您在分隔符周围使用单引号

开头分隔符后的行其余部分不被解释为字符串的一部分,这意味着您可以执行以下操作

strings = [<<END, "short", "strings"]
a long string
END

=> ["a long string\n", "short", "strings"]

您甚至可以“堆叠”多个 here document

string = [<<ONE, <<TWO, <<THREE]
  the first thing
ONE
  the second thing
TWO
  and the third thing
THREE
=> ["the first thing\n", "the second thing\n", "and the third thing\n"]

您甚至可以应用方法

s = <<END.chomp.upcase # Stripped of ending new-line and uppercased.
abc
END
=> "ABC"

命令扩展

[编辑 | 编辑源代码]

您可以使用反引号引起来的字符串执行 shell 命令并运行任何外部程序,并获取输出。

# Print contents of current directory, just like in console window.
puts `dir`
# Resolve a domain name to its IP address.
domain = 'ruby-lang.org'
ip = `nslookup #{domain}`.match(/\d+\.\d+\.\d+\.\d+/).to_s # => 151.101.85.178
# Download this web-page with "curl", displaying the progress, then find and print an example from it.
puts `curl https://wikibooks.cn/w/index.php?title=Ruby_Programming/Syntax/Literals`.encode('utf-8')
  .match(%r(<h2(?:.(?!</h2>))*Numerics.*?(?=<h2))imsu).to_s    # Reducing to one section.
  .match(%r((?<=<pre>).*?(?=</pre>))imsu ).to_s                # Reducing to an example in it.

正则表达式

[编辑 | 编辑源代码]
regex_one = /chapter_\d+/i #=> /chapter_\d+/i
regex_two = %r(/chapter_\d+)i #=> /\/chapter_\d+/i

数组是由非负整数索引的多个对象的集合。您可以通过编写 Array.new、编写方括号内可选的用逗号分隔的值列表,或者如果数组只包含字符串对象,则编写以 %w 开头的用空格分隔的字符串来创建数组对象。

array_one   = Array.new
array_two   = []                # shorthand for Array.new
array_three = ["a", "b", "c"]   # array_three contains "a", "b" and "c"
array_four  = %w[a b c d e f g] # array_four also contains "a", "b" and "c"
array_three[0]                # => "a"
array_three[2]                # => "c"
array_four[0]                 # => "a"
#negative indices are counted back from the end
array_four[-2]                # => "f"
#[start, count] indexing returns an array of count objects beginning at index start
array_four[1,3]               # => ["b", "c", "d"]
#using ranges. The end position is included with two periods but not with three
array_four[0..4]              # => ["a", "b", "c", "d", "e"]
array_four[0...4]             # => ["a", "b", "c", "d"]

最后一种方法,使用 %w,本质上是当子字符串仅用空格分隔时,String 方法 split 的简写。在以下示例中,前两种创建字符串数组的方法在功能上是相同的,而最后两种方法创建了截然不同的(但都有效的)数组。

 array_one   = %w'apple orange pear'            # => ["apple", "orange", "pear"]
 array_two   = 'apple orange pear'.split        # => ["apple", "orange", "pear"]
 array_one   == array_two                       # => true
 array_three = %w'dog:cat:bird'                 # => ["dog:cat:bird"]
 array_four  = 'dog:cat:bird'.split(':')        # => ["dog", "cat", "bird"]
 array_three == array_four                      # => false

哈希基本上与数组相同,只是哈希不仅包含值,还包含指向这些值的键。每个键在哈希中只能出现一次。哈希对象通过编写 Hash.new 或编写花括号内可选的用逗号分隔的 key => value 对列表来创建。

hash_one   = Hash.new
hash_two   = {}                             # shorthand for Hash.new
hash_three = {"a" => 1, "b" => 2, "c" => 3} #=> {"a"=>1, "b"=>2, "c"=>3}

通常,符号 用于哈希键(允许更快地访问),因此您会看到哈希声明如下

hash_sym   = { :a => 1, :b => 2, :c => 3}   #=> {:b=>2, :c=>3, :a=>1}
hash_sym   = { a: 1, b: 2, c: 3}            #=> {:b=>2, :c=>3, :a=>1}

后一种形式是在 Ruby 1.9 中引入的。

哈希排序

[编辑 | 编辑源代码]

请注意,在 1.8 中,遍历哈希将按照“随机”顺序遍历键值对。从 1.9 开始,它将按照插入顺序遍历它们。但是请注意,如果您在不先删除的情况下重新插入键,或者更改了现有键的值,则键在迭代中的顺序不会改变。

>> a = {:a => 1, :b => 2, :c => 3}
=> {:a=>1, :b=>2, :c=>3}
>> a.keys # iterate over, show me the keys
=> [:a, :b, :c]
>> a[:b] = 2
> a.keys
=> [:a, :b, :c] # same order
>> a.delete(:b)
>> a[:b] = 4 # re insert now
=> 4
>> a.keys
=> [:a, :c, :b] # different order

范围表示类型所有可能值的子集,更准确地说,是起始值和结束值之间所有可能的值。

这可能是

  • 0 到 5 之间的所有整数。
  • 0 到 1 之间的所有数字(包括非整数),但不包括 1。
  • 't' 到 'y' 之间的所有字符。

在 Ruby 中,这些范围由以下表示

0..5
0.0...1.0
't'..'y'

因此,范围由起始值、结束值以及是否包含结束值(在此简短语法中,使用两个点表示包含,三个点表示不包含)组成。

范围表示一组值,而不是一个序列。因此,

5..0

虽然语法正确,但会产生长度为零的范围。

范围只能从同一个类的实例或公共父类的子类中形成,该父类必须是 Comparable(实现 <=>)。

范围是 Range 类的实例,具有一些方法,例如,确定某个值是否在范围内

r = 0..5
puts r === 4  # => true
puts r === 7  # => false

有关所有 Range 方法的详细信息,请参阅 Range 类参考

这里 是关于它们用法的教程。

华夏公益教科书