# Tcl 中的字符串

> 原文： [https://zetcode.com/lang/tcl/strings/](https://zetcode.com/lang/tcl/strings/)

在 Tcl 教程的这一部分中，我们将更详细地处理字符串数据。 字符串是计算机语言中的一种重要数据类型。

字符串是字符序列。 与其他语言不同，Tcl 中的字符串不必总是用双引号引起来。 仅当单词之间有空格时，它们才是必需的。 Tcl 是基于字符串的语言。 它提供了一组丰富的用于处理字符串的命令。

## 第一个例子

下面是一个显示一些字符串的简单示例。

```tcl
#!/usr/bin/tclsh

puts Tcl
puts Java
puts Falcon

puts "Tcl language"
puts {Tcl language}

```

该脚本将一些字符串值打印到控制台。

```tcl
puts Tcl
puts Java
puts Falcon

```

Tcl 中的字符串不必总是用引号引起来。

```tcl
puts "Tcl language"
puts {Tcl language}

```

Tcl 中的字符串可以用双引号或大括号括起来。

```tcl
$ ./simple_strings.tcl 
Tcl
Java
Falcon
Tcl language
Tcl language

```

这是`simple.tcl`脚本的输出。

## 使用引号

如果我们想在直接演讲中显示报价该怎么办？ 在这种情况下，必须对内引号进行转义。

```tcl
$ cat directspeech.tcl
#!/usr/bin/tclsh

puts "There are many stars"
puts "He said, \"Which one is your favourite?\""

```

我们使用`\`字符转义其他引号。

```tcl
$ ./directspeech.tcl
There are many stars
He said, "Which one is your favourite?"

```

`directspeech.tcl`程序的输出。

## 多行字符串

在 Tcl 中创建多行字符串非常容易。 在创建多行字符串的许多其他语言中，我使用起来不那么方便。

```tcl
#!/usr/bin/tclsh

set lyrics "I cheated myself
like I knew I would
I told ya, I was trouble
you know that I'm no good"

puts $lyrics

```

我们简单地继续下一行。 如果我们想显示经文，这很有用。

```tcl
$ ./multiline.tcl
I cheated myself
like I knew I would
I told ya, I was trouble
you know that I'm no good

```

## 比较字符串

字符串的基本比较可以通过`string compare`命令完成。

```tcl
#!/usr/bin/tclsh

puts [string compare 12 12]
puts [string compare Eagle Eagle]
puts [string compare Eagle eagle]
puts [string compare -nocase Eagle eagle]

```

`string compare`命令逐字符比较字符串。 如果发现两个字符串的第一个字符相等，则继续第二个字符，直到结尾。 如果字符串相等，则返回 0；如果第一个字符串中的不匹配字符位于 ASCII 表中的第二个字符串之前，则返回 -1。 如果第一个字符串的不匹配字符位于第二个字符串的字符之后，则返回 1。

```tcl
puts [string compare 12 12]

```

在这种情况下，12 是字符串。

```tcl
puts [string compare Eagle Eagle]

```

两个字符串相等，将 0 打印到控制台。

```tcl
puts [string compare Eagle eagle]

```

`E`位于`e`之前，因此返回-1。

```tcl
puts [string compare -nocase Eagle eagle]

```

使用`-nocase`选项，我们将忽略大小写。 这两个字符串相等。

```tcl
$ ./compare.tcl
0
0
-1
0

```

程序的输出。

`string equal`也可以用来比较字符串。 如果字符串相等，则命令返回 1，否则返回 0。

```tcl
#!/usr/bin/tclsh

set str1 Tcl
set str2 "Tcl language"

puts [string compare $str1 $str2]
puts [string compare -length 3 $str1 $str2]

puts [string equal $str1 $str2]
puts [string equal -length 3 $str1 $str2]

```

该脚本显示了两个比较字符串的命令。

```tcl
puts [string compare $str1 $str2]

```

该行打印 -1。 前三个位置的字符相等。 在第四个位置，`string compare`命令将空格与`l`字符进行比较。 该空格位于 ASCII 表中的`l`字符之前。 字符串不相等。

```tcl
puts [string compare -length 3 $str1 $str2]

```

在这种情况下，我们将比较限制为前三个字符。 它们在两个字符串中都相同，因此命令返回 0。

```tcl
puts [string equal $str1 $str2]

```

这两个字符串不相同，因此`string equal`命令返回 0，表示为`false`。

```tcl
puts [string equal -length 3 $str1 $str2]

```

将字符串限制为前三个字符，该命令返回 1。这意味着直到前三个字符为止它们都是相同的。

## 模式匹配

对于简单的模式匹配-球形-我们可以使用`string match`命令。 对于更强大的模式匹配，我们可以利用`regexp`命令。

```tcl
#!/usr/bin/tclsh

puts [string match book???? bookcase] 

puts [regexp {[a-z]{3}} "abc"]
puts [regexp {[^a-z]{3}} "abc"]
puts [regexp book(shelf|worm) bookworm] 

```

该示例演示了`string match`和`regexp`命令的用法。 对于匹配项，它们返回 1，对于不匹配项，返回 0。

```tcl
$ ./string_match.tcl 
1
1
0
1

```

`string_match1.tcl`程序的输出。

## Unicode

我们可以在 Tcl 脚本中使用 Unicode 字符串。

```tcl
#!/usr/bin/tclsh

puts "La femme vit par le sentiment, là où l'homme vit par l'action"
puts "Анна Каренина"

```

我们将两个消息打印到终端。 第一是法语，第二是俄语。

```tcl
$ ./unicode.tcl
La femme vit par le sentiment, là où l'homme vit par l'action
Анна Каренина

```

输出。

## 字符串命令

Tcl 具有有用的内置命令，可用于处理字符串。

```tcl
#!/usr/bin/tclsh

set str Eagle

puts [string length $str]

puts [string index $str 0]
puts [string index $str end]

puts [string range $str 1 3]

```

我们定义一个字符串变量并使用一些字符串命令。

```tcl
puts [string length $str]

```

`string length`返回字符串中的字符数。

```tcl
puts [string index $str 0]
puts [string index $str end]

```

`string index`命令在特定位置返回字符。

```tcl
puts [string range $str 1 3]

```

`string range`返回由第一个和最后一个索引选择的字符范围。

```tcl
$ ./strings1.tcl
5
E
e
agl

```

输出。

我们有一个`split`命令将字符串拆分为特定字符。 该命令返回单词列表。 可以使用`join`命令将这些单词组合成一个字符串。

```tcl
#!/usr/bin/tclsh

set langs "Tcl,Java,C,C#,Ruby,Falcon"

puts [split $langs ,]
puts [join [split $langs ","] ":"]

```

在我们的程序中，我们将拆分并连接字符串。

```tcl
set langs "Tcl,Java,C,C#,Ruby,Falcon"

```

这是我们将要拆分的字符串。 有几个单词，以逗号分隔。 逗号字符是用来分割字符串的字符。

```tcl
puts [split $langs ,]

```

该行显示了我们从字符串中拆分出的所有单词。

```tcl
puts [join [split $langs ","] ":"]

```

`split`命令返回字符串中的单词列表。 然后将这些词合并在一起。 单词现在将由冒号分隔。

```tcl
$ ./splitjoin.tcl 
Tcl Java C C# Ruby Falcon
Tcl:Java:C:C#:Ruby:Falcon

```

示例的输出。

接下来，我们将使用另一个带有几个字符串命令的示例。

```tcl
#!/usr/bin/tclsh

set str "ZetCode" 

puts [string toupper $str]
puts [string tolower $str]
puts [string totitle $str]
puts [string reverse $str]

```

我们介绍了四个字符串命令。 这些命令不会更改原始字符串。 它们返回一个新的，经过修改的字符串。

```tcl
puts [string toupper $str]

```

我们将字符转换为大写。

```tcl
puts [string tolower $str]

```

我们将字符串的字母转换为小写。

```tcl
puts [string totitle $str]

```

`string totitle`返回一个字符串，其首字母大写； 其他字符均为小写。

```tcl
puts [string reverse $str]

```

我们使用`string reverse`命令反转字符串的字符。

```tcl
$ ./strings2.tcl 
ZETCODE
zetcode
Zetcode
edoCteZ

```

运行程序。

## 格式化字符串

字符串的最基本格式在引号内完成。

```tcl
#!/usr/bin/tclsh

set oranges 2
set apples 4
set bananas 3

puts "There are $oranges oranges, $apples apples and\
$bananas bananas. "

```

Tcl 用双引号求值变量。

```tcl
puts "There are $oranges oranges, $apples apples and\
$bananas bananas. "

```

在此代码行中，我们将变量和字符串组合在一个句子中。

```tcl
$ ./fruit.tcl
There are 2 oranges, 4 apples, and 3 bananas.

```

输出。

可以使用`format`命令完成更高级的格式化。 它具有以下概要：

```tcl
format formatString ?arg arg ...?

```

`formatString`用于控制参数的显示方式。 该命令可以使用多个参数。

```tcl
#!/usr/bin/tclsh

puts [format %s "Inception movie"]
puts [format "%d %s" 23 songs]

```

这是基本脚本，显示`format`命令的用法。

```tcl
puts [format %s "Inception movie"]

```

该行仅将字符串输出到控制台。

```tcl
puts [format "%d %s" 23 songs]

```

在这里，我们打印两个参数。 每个参数都有一个格式说明符，该说明符以`%`字符开头。

```tcl
$ ./basicformat.tcl
Inception movie
23 songs

```

输出。

现在，我们显示`format`命令的一些基本转换说明符。 `%s`，`%f`，`%d`和`%e`是转换类型。 它们控制如何显示值。 转换类型是转换说明符的唯一必需部分。

```tcl
#!/usr/bin/tclsh

puts [format "%s" "Tcl language"]
puts [format "%f" 212.432]
puts [format "%d" 20000]
puts [format "%e" 212.342]

```

我们将在终端上打印四则消息。

```tcl
puts [format "%s" "Tcl language"]

```

`%s`是字符串的转换类型。

```tcl
puts [format "%f" 212.432]

```

`%f`用于显示十进制数字。

```tcl
puts [format "%d" 20000]

```

要打印整数值，我们使用`%d`转换类型。

```tcl
puts [format "%e" 212.342]

```

`%e`用于以科学格式显示数字。

```tcl
$ ./format.tcl
Tcl language
212.432000
20000
2.123420e+02

```

输出。

在下一个示例中，我们将以三种不同的数字格式设置数字格式。

```tcl
#!/usr/bin/tclsh

puts [format "%-10s %-14s %s" Decimal Hexadecimal Octal]

puts [format "%-10d %-14x %o" 5000 5000 5000]
puts [format "%-10d %-14x %o" 344 344 344]
puts [format "%-10d %-14x %o" 55 55 55]
puts [format "%-10d %-14x %o" 9 9 9]
puts [format "%-10d %-14x %o" 15666 15666 15666]

```

我们以十进制，十六进制和八进制格式打印数字。 我们还将数字对齐三列。

```tcl
puts [format "%-10d %-14x %o" 5000 5000 5000]

```

`%-10d`适用于第一个数字，`%-14x`适用于第二个数字，`%o`适用于第三个数字。 我们将描述第一个。 格式说明符以`%`字符开头。 负号`-`表示如果该值短于字段宽度，则将其对齐。 其余字段填充空白。 数字 10 指定字段宽度。 最后，`d`字符表明数字以十进制格式显示。 `x`代表十六进制，`o`代表八进制。

```tcl
$ ./numbers.tcl
Decimal    Hexadecimal    Octal
5000       1388           11610
344        158            530
55         37             67
9          9              11
15666      3d32           36462

```

运行示例。

最后，我们将格式化日期和时间数据。 我们使用`clock format`命令。

```tcl
#!/usr/bin/tclsh

set secs [clock seconds]

puts "Short date: [clock format $secs -format %D]"
puts "Long date: [clock format $secs -format "%A, %B %d, %Y"]"
puts "Short time: [clock format $secs -format %R]"
puts "Long time: [clock format $secs -format %r]"
puts "Month: [clock format $secs -format %B]"
puts "Year: [clock format $secs -format %Y]"

```

前面的示例演示了一些常见的日期和时间格式。

```tcl
set secs [clock seconds]

```

我们以秒为单位获取当前时间戳。 此值随后传递给`clock format`命令，以使人类可以读取日期和时间。

```tcl
puts "Short date: [clock format $secs -format %D]"

```

日期格式由`-format`选项控制。 有几种说明符。 `%D`以月/日/年格式返回日期。

```tcl
$ ./clockformat.tcl
Short date: 04/11/2011
Long date: Monday, April 11, 2011
Short time: 11:30
Long time: 11:30:30 am
Month: April
Year: 2011

```

输出。

Tcl 教程的这一部分介绍了字符串。