Elixir - 字符串



Elixir 中的字符串用双引号括起来,并且使用 UTF-8 编码。与 C 和 C++ 中默认使用 ASCII 编码且仅支持 256 个不同字符不同,UTF-8 包含 1,112,064 个码位。这意味着 UTF-8 编码包含这么多不同的可能字符。由于字符串使用 utf-8,我们也可以使用诸如 ö、ł 等符号。

创建字符串

要创建字符串变量,只需将字符串赋值给变量即可:

str = "Hello world"

要将其打印到控制台,只需调用 **IO.puts** 函数并将其传递变量 str 即可:

str = str = "Hello world" 
IO.puts(str)

上述程序生成以下结果:

Hello World

空字符串

可以使用字符串字面量 **""** 创建空字符串。例如,

a = ""
if String.length(a) === 0 do
   IO.puts("a is an empty string")
end

上述程序生成以下结果。

a is an empty string

字符串插值

字符串插值是一种通过将常量、变量、字面量和表达式的值包含在字符串字面量中来构建新的字符串值的方法。Elixir 支持字符串插值,在编写字符串时使用变量,将其用花括号括起来并在花括号前加上 **'#'** 符号。

例如,

x = "Apocalypse" 
y = "X-men #{x}"
IO.puts(y)

这将获取 x 的值并将其替换到 y 中。上述代码将生成以下结果:

X-men Apocalypse

字符串连接

我们已经在前面的章节中看到了字符串连接的使用。**'<>'** 运算符用于在 Elixir 中连接字符串。要连接两个字符串,

x = "Dark"
y = "Knight"
z = x <> " " <> y
IO.puts(z)

上述代码生成以下结果:

Dark Knight

字符串长度

要获取字符串的长度,我们使用 **String.length** 函数。将字符串作为参数传递,它将显示其大小。例如,

IO.puts(String.length("Hello"))

运行上述程序时,它会产生以下结果:

5

反转字符串

要反转字符串,将其传递给 String.reverse 函数。例如,

IO.puts(String.reverse("Elixir"))

上述程序生成以下结果:

rixilE

字符串比较

要比较两个字符串,可以使用 == 或 === 运算符。例如,

var_1 = "Hello world"
var_2 = "Hello Elixir"
if var_1 === var_2 do
   IO.puts("#{var_1} and #{var_2} are the same")
else
   IO.puts("#{var_1} and #{var_2} are not the same")
end

上述程序生成以下结果:

Hello world and Hello elixir are not the same.

字符串匹配

我们已经看到了 =~ 字符串匹配运算符的使用。要检查字符串是否与正则表达式匹配,我们还可以使用字符串匹配运算符或 String.match? 函数。例如,

IO.puts(String.match?("foo", ~r/foo/))
IO.puts(String.match?("bar", ~r/foo/))

上述程序生成以下结果:

true 
false

这也可以通过使用 =~ 运算符来实现。例如,

IO.puts("foo" =~ ~r/foo/)

上述程序生成以下结果:

true

字符串函数

Elixir 支持大量与字符串相关的函数,以下表格列出了一些最常用的函数。

序号 函数及其用途
1

at(string, position)

返回给定 utf8 字符串中 position 位置的字符。如果 position 大于字符串长度,则返回 nil

2

capitalize(string)

将给定字符串中的第一个字符转换为大写,其余字符转换为小写

3

contains?(string, contents)

检查字符串是否包含任何给定的内容

4

downcase(string)

将给定字符串中的所有字符转换为小写

5

ends_with?(string, suffixes)

如果字符串以任何给定的后缀结尾,则返回 true

6

first(string)

返回 utf8 字符串中的第一个字符,如果字符串为空则返回 nil

7

last(string)

返回 utf8 字符串中的最后一个字符,如果字符串为空则返回 nil

8

replace(subject, pattern, replacement, options \\ [])

返回一个新字符串,该字符串通过用 replacement 替换 subject 中 pattern 的出现次数来创建

9

slice(string, start, len)

返回从偏移量 start 开始,长度为 len 的子字符串

10

split(string)

将字符串在每个 Unicode 空格处分割成子字符串,忽略前导和尾随空格。空格组被视为单个出现。分割不会发生在不间断空格上

11

upcase(string)

将给定字符串中的所有字符转换为大写

二进制

二进制只是一系列字节。二进制使用 **<< >>** 定义。例如

<< 0, 1, 2, 3 >>

当然,这些字节可以以任何方式组织,甚至以不使它们成为有效字符串的序列组织。例如,

<< 239, 191, 191 >>

字符串也是二进制。并且字符串连接运算符 **<>** 实际上是一个二进制连接运算符

IO.puts(<< 0, 1 >> <> << 2, 3 >>)

上述代码生成以下结果:

<< 0, 1, 2, 3 >>

注意 ł 字符。由于它是 utf-8 编码,因此此字符表示占用 2 个字节。

由于二进制中表示的每个数字都表示一个字节,因此当此值从 255 上升时,它会被截断。为了防止这种情况,我们使用大小修饰符来指定我们希望该数字占用多少位。例如:

IO.puts(<< 256 >>) # truncated, it'll print << 0 >>
IO.puts(<< 256 :: size(16) >>) #Takes 16 bits/2 bytes, will print << 1, 0 >>

上述程序将生成以下结果:

<< 0 >>
<< 1, 0 >>

如果字符是码位,我们也可以使用 utf8 修饰符,则它将在输出中产生;否则为字节:

IO.puts(<< 256 :: utf8 >>)

上述程序生成以下结果:

Ā

我们还有一个名为 **is_binary** 的函数,它检查给定变量是否为二进制。请注意,只有存储为 8 位倍数的变量才是二进制。

比特串

如果我们使用大小修饰符定义二进制并向其传递不是 8 的倍数的值,则最终会得到比特串而不是二进制。例如,

bs = << 1 :: size(1) >>
IO.puts(bs)
IO.puts(is_binary(bs))
IO.puts(is_bitstring(bs))

上述程序生成以下结果:

<< 1::size(1) >>
false
true

这意味着变量 **bs** 不是二进制而是比特串。我们也可以说二进制是比特串,其中比特数可以被 8 整除。模式匹配以相同的方式作用于二进制和比特串。

广告