跳转到内容

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 元-x
\M-\C-x 元控制-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 文档" 表示法

[编辑 | 编辑源代码]

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

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

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

有一种更漂亮的方式来编写 here 文档,它允许结束分隔符通过空格缩进

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 文档是插值的,除非您在分隔符周围使用单引号

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

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

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

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

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 类参考

这里 是一个关于其用法的教程。

华夏公益教科书