Perl 编程/字符串
任何作为单个单元组合在一起的字符序列都是字符串。所以,单词the是一个字符串。这句话是一个字符串。甚至整个段落都是一个字符串。事实上,您可以将本书的全部文本视为一个字符串。
字符串可以是任何长度,并且可以包含任何字符、数字、标点符号、特殊字符(如! # 和%),甚至包含英语以外的自然语言中的字符。此外,字符串可以包含特殊的空格格式化字符,如换行符、制表符和铃声字符。我们稍后将更详细地讨论特殊字符。现在,我们将从考虑如何在 Perl 程序中插入字面字符串开始考虑字符串。
为了开始我们对 Perl 中字符串的讨论,我们将考虑如何在 Perl 中使用字符串字面量。这里的单词字面量指的是当您想要直接在 Perl 中键入字符串时使用。这可以与将字符串存储在变量中形成对比。
任何字符串字面量都可以用作表达式。当我们想要将字符串字面量存储在变量中时,我们会发现这很有用。但是,现在,我们只会考虑可以在 Perl 中创建的不同类型的字符串字面量。稍后,我们将学习如何在标量变量部分中将这些字符串字面量分配给变量。
字符串字面量主要可以通过三种方式在 Perl 中表示。我们已经在简单的编程示例中使用了一种类型,使用双引号。在 Perl 中使用双引号或单引号各有其特殊的含义。
单引号可以被认为是字面字符串。在前面的示例中,您可能已经注意到变量名称包含在用双引号括起来的字符串中。当结果被打印时,变量的值被放置在打印的行中,而不是变量的名称。如果使用单引号,则会打印实际的变量名,因为使用单引号时,几乎所有可能以不同方式解释的特殊字符都按字面值处理。
要了解这是什么意思,请尝试以下简单程序
my $name = "Fred";
print "Hello, $name\n";
print 'Hello, $name\n';
您应该在第一行看到“Hello Fred”,在第二行看到“Hello $name\n”(后面没有换行符)。将值$name放入第一个 print 语句中的字符串称为“插值”。如果您不需要插值,则应该使用单引号,因为它使您的意图更清晰。
单引号字符串中有两个字符并不总是代表自身。这是由于必要性,因为单引号字符串以'字符开始和结束。我们需要一种方法来表达在单引号字符串内我们希望字符串包含一个'字符。
解决此问题的方法是在任何'字符之前加上反斜杠(\字符),我们实际上希望它出现在字符串本身中。因此,我们有这样的字符串
'xxx\'xxx'; # xxx, a single-quote character, and then xxx
在这个例子中,我们恰好有一个包含七个字符的字符串。即,这是字符串xxx'xxx。一开始可能难以适应 Perl 的输入中的两个字符实际上只在字符串本身中产生一个字符的想法。(C 程序员可能已经习惯了这个想法。)但是,只要记住规则,您可能会很快习惯它们。
由于我们已经使用\字符对'字符执行了一些特殊操作,因此我们现在必须担心反斜杠字符本身的特殊情况。当我们在单引号字符串中看到一个\字符时,我们必须仔细考虑会发生什么。
在大多数情况下,当\在单引号字符串中时,它只是一个反斜杠,代表它自己,就像大多数其他字符一样。但是,以下例外情况适用
- 序列\'在实际字符串中产生字符'。(这是我们上面已经讨论过的例外情况)。
- 序列\\在实际字符串中产生字符\在实际字符串中。换句话说,两个彼此相邻的反斜杠实际上只产生一个反斜杠。
- 反斜杠本身不能放在单引号字符串的末尾。这不可能发生,因为 Perl 会认为您正在使用\转义结束的'.
以下示例说明了各种例外情况,并正确地使用了它们
'I don\'t think so.'; # Note the ' inside is escaped with \
'Need a \\ (backslash) or \?'; # The \\ gives us \, as does \
'You can do this: \\'; # A single backslash at the end
'Three \\\'s: "\\\\\"'; # There are three \ chars between ""
在最后一个示例中,请注意结果字符串为Three \'s: "\\\"。如果您能理解该示例,那么您肯定已经掌握了单引号字符串的工作原理!
除了难以阅读的反斜杠转义之外,Perl 还提供了其他方法来引用字符串。上面的第一个示例可以写成
q{I don't think so}; # No \ needed to escape the '
请注意,没有规则禁止单引号字符串跨越多行。当您这样做时,字符串中嵌入了换行符。
换行符是一个特殊的 ASCII 字符,表示应开始新行。在文本编辑器中或将输出打印到屏幕上时,这通常表示光标应从当前行的末尾移动到其后一行的第一个位置。
由于 Perl 允许将这些换行符直接放置到单引号字符串中,因此我们可以执行以下操作
'Time to
start anew.'; # Represents the single string composed of:
# 'Time to' followed by a newline, followed by
# 'start anew.'
此字符串共有二十个字符。前七个是Time to。下一个字符是换行符。然后是十一个字符,start anew.跟随。再次注意,这是一个字符串,其第八个字符是换行符。
此外,请注意,我们不允许在字符串中间放置注释,即使我们通常允许在行的任何位置放置#并将该行其余部分作为注释。我们不能在这里这样做,因为我们还没有用'终止我们的单引号字符串,因此,任何#字符和其后的注释实际上都会成为单引号字符串的一部分!请记住,单引号字符串以'开头,以'结尾,介于两者之间的所有内容都被视为字符串的一部分,包括换行符、#字符和其他任何内容。
在完成我们对单引号字符串的讨论时,请考虑以下这些不合法的字符串示例,因为它们违反了我们上面讨论的例外情况
'You cannot do this: \'; # INVALID: the ending \ cannot be alone
'It is 5 o'clock!' # INVALID: the ' in o'clock should be escaped
'Three \\\'s: \\\\\'; # INVALID: the final \ escapes the ', thus
# the literal is not terminated
'This is my string; # INVALID: missing close quote
有时,当您有如上例所示的无效字符串字面量时,Perl 给出的错误消息不是特别直观。但是,当您看到诸如
(Might be a runaway multi-line '' string starting on line X) Bareword found where operator expected Bareword "foo" not allowed while "strict subs" in use
之类的错误消息时,这通常表示您有失控或无效的字符串。注意这些问题。很有可能,您最终会忘记并违反单引号字符串的规则之一,然后需要确定为什么无法运行您的 Perl 程序。
在我们继续讨论双引号字符串之前,有必要先进行一个小小的偏离。我们知道如何在 Perl 中表示字符串,但是,您可能已经注意到,我们迄今为止给出的示例并没有做任何有趣的事情。如果您尝试将我们列为示例的语句放入单引号字符串中,像这样
#!/usr/bin/perl
use strict; use warnings;
'Three \\\'s: "\\\\\"'; # There are three \ chars between "" 'xxx\'xxx'; # xxx, a single-quote character, and then xxx 'Time to start anew.';
您可能注意到没有任何有趣的事情发生。Perl 很乐意运行此程序,但它不会产生任何输出。
因此,为了开始在 Perl 中处理字符串,超越简单的假设考虑,我们需要一种方法让 Perl 为我们显示我们的字符串。在 Perl 中实现此目的的规范方法是使用print
函数。Perl 中的print
函数可以以多种方式使用。最简单的形式是使用语句print STRING;,其中STRING是任何有效的 Perl 字符串。因此,为了重新考虑我们的示例,我们可以打印出每个字符串,而不是简单地列出它们
#!/usr/bin/perl
use strict; use warnings;
print 'Three \\\'s: "\\\\\"'; # Print first string print 'xxx\'xxx'; # Print the second print 'Time to start anew. '; # Print last string, with a newline at the end
此程序将产生输出。运行时,输出将发送到所谓的标准输出。这通常是您运行 Perl 程序的终端、控制台或窗口。对于上面的程序,标准输出的输出如下
Three \'s: "\\\"xxx'xxxTime to start anew.
请注意,需要换行符来分隔行。因此,如果您希望您的字符串成为输出中该行的最后一项,则需要在每个有效字符串的末尾添加换行符。
请注意,在输出的最后一个字符串的末尾放置换行符尤其重要。如果不这样做,通常您正在使用的命令解释器的命令提示符可能会与您的最后一行输出合并在一起,这可能会令人非常困惑。因此,始终记住在每行的末尾放置换行符,尤其是在输出的最后一行。
最后,您可能已经注意到,在单引号字符串中间使用换行符来格式化代码会损害可读性。因为您在单引号字符串内,所以您无法更改 print 语句中续行的格式,也无法在这些行的末尾添加注释,因为这会将数据插入到您的单引号字符串中。为了更优雅地处理换行符,您应该使用双引号字符串,这是下一节的主题。
双引号字符串是表示 Perl 中标量字符串字面量的另一种方式。与单引号字符串一样,您将一组 ASCII 字符放在两个分隔符之间(在本例中,我们的分隔符是")。但是,当您使用双引号字符串时,会发生称为插值的操作。
插值是一个特殊的处理过程,其中用 ASCII 编写的某些特殊字符串被替换为不同的内容。在单引号字符串部分中,我们注意到单引号字符串中的某些序列(即,\\和\')被不同地处理 - 这些称为反斜杠转义序列。这与插值发生的情况非常相似。
例如,在插值的双引号字符串中,各种以\字符开头的序列根据下表中的内容进行不同的处理
字符串 | 插值为 |
\\ | 一个实际的单个反斜杠字符 |
\$ | 一个单个 $ 字符 |
\@ | 一个单个 @ 字符 |
\" | 一个单个双引号字符 |
\t | 制表符 |
\n | 换行符 |
\r | 回车 |
\f | 换页 |
\b | 退格 |
\a | 警报(铃声) |
\e | 转义 |
\056 | 由八进制值表示的字符,056(与.) |
\x2E | 由十六进制值表示的字符,2E(与.) |
您可能在上一章中已经注意到,您可以在字符串中放置变量的名称及其前导美元符号。这种形式的插值将字符串中变量的名称替换为变量的内容。
让我们考虑一个使用其中几个字符的示例
#!/usr/bin/perl
use strict; use warnings;
print "A backslash: \\\n"; print "Tab follows:\tover here\n"; print "Ring! \a\n"; print "Please pay someone\@example.org \$20.\n";
此程序运行时,会在屏幕上产生以下输出
A backslash: \ Tab follows: over here Ring! Please pay [email protected] $20.
此外,运行时,您应该听到计算机发出蜂鸣声。那是\a字符的输出,您无法在屏幕上看到它。但是,您应该能够听到它。
请注意,\n字符结束一行。\n应始终用于结束一行。熟悉 C 语言的学生习惯于使用此序列来表示换行符。在编写 Perl 时,换行符一词和\n字符大致同义。
运算符以某种方式操作两个或多个字符串。
Perl 使用.运算符连接或连接两个字符串,如下所示
"Hello" . "World" # This is the same as "HelloWorld"
如果您希望字符串在 Hello 和 World 之间有一个空格,您可以这样编写
"Hello" . ", " . "World" # This is the same as "Hello, World"
或者像这样
"Hello" . ", World" # This is the same as "Hello, World"
这称为字符串重复运算符,用于重复字符串。您只需将字符串放在x左侧,并将数字放在右侧即可。像这样
"Hello" x 5 # This is the same as "HelloHelloHelloHelloHello"
如果您希望在每次输出字符串后插入换行符,请使用
"Hello\n" x 5
- 编写一个使用.运算符打印“Hello, Sir!”的程序。
- 编写另一个使用x运算符打印“HelloHelloHelloHello”的程序。在此程序中添加注释以解释其工作原理
- 请记住,花些时间练习使用单引号和双引号字符串,练习得越多,您就会越熟练。