文章目录
- 一、字符串
- 二、常用命令
- 1. string
- string bytelength str
- string length str
- string compare ? -nocase? ? -length int? str1 str2
- string equal ? -nocase? ? -length int? str1 str2
- string first ?-exact? substring string ?start?
- string last ?substring string ?last?
- string index str charIndex
- string is class ?-strict? ?-failindex varname? str
- string map -nocase? mapping str
- string match $str1 $str2
- string range str first last
- string repeat str count
- string replace str first last ? newstring?
- string reverse str
- string tolower str ? first? ? last?
- string totitle str ? first? ? last?
- string toupper str ? first? ? last?
- string trim str ? chars?
- string trimleft str ? chars?
- string trimright str ? chars?
- string wordend str charIndex
- string wordstart str charIndex
- 2. regexp
- 3. regsub
- 4. format
- 5. scan
一、字符串
TCL中的字符串可以使用单引号或双引号括起来,还支持使用花括号来表示字符串。
代码如下(示例):
set text "Hello World"
set text ‘Hello World’
set text {Hello World}
#执行结果
Hello World
Hello World
Hello World
二、常用命令
因为 TCL 把所有的输入都当作字符串看待,所以 TCL 提供了较强的字符串操作功能,TCL 中与 字符串操作有关的命令有:string、format、regexp、regsub、scan 等。
1. string
语法:string option arg ?arg…?
string 命令具有强大的操作字符串的功能。
string bytelength str
命令都是返回字符串string的长度。bytelength是计算一个字符串的字节数。
代码如下(示例):
string bytelength "This is a tcltk example"
string bytelength "这是一个tcltk示例"
#执行结果
23
23 #一个中文为三个字节
string length str
命令都是返回字符串string的长度。length是计算一个字符串的长度,如果字符串为标准的ASCII码组成,那么bytelength和length两个命令得到的结果是相同的。
代码如下(示例):
string length "This is a tcltk example"
string length "这是一个tcltk示例"
#执行结果
23
11
string compare ? -nocase? ? -length int? str1 str2
命令返回两个字符串比较的结果,str1的顺序比str2靠前就返回1,反之返回-1,相等返回0。
-nocase的意思就是不区分大小写。
-length int中的int就是需要比较的前面几个字符。
代码如下(示例):
string compare "This is a TCLTK example" "This is a tcltk example"
string compare "This is a tcltk example" "This is a TCLTK example"
string compare "This is a tcltk example" "This is a tcltk example"
string compare -nocase "This is a TCLTK example" "This is a tcltk example"
string compare -length 7 "This is a TCLTK example" "This is a tcltk example"
#执行结果
-1 #因为ASCII码T在t之后,所以从顺序上来说后面的字符串显然在前,所以返回-1
1
0 #如果两个字符串相同则返回0
0 #因为不区分大小写,所以两个字符串对比结果相等
0 #只比较字符串的前7个字符"This is",前面的7个字符是相同的,所以返回0
string equal ? -nocase? ? -length int? str1 str2
这个命令比较两个字符串是否相同。相同返回1,不同返回0。
代码如下(示例):
string equal "This is a TCLTK example" "This is a tcltk example"
string equal "This is a tcltk example" "This is a tcltk example"
#执行结果
-1
0
string first ?-exact? substring string ?start?
- substring:是要查找的子字符串。
- string:是被查找的字符串。
- start:是可选参数,表示从字符串的哪个位置开始查找,默认是从字符串的开头开始。
代码如下(示例):
string first "tcltk" "This is a tcltk example"
string first "is" "This is a tcltk example" 4
string first "is" "This is a tcltk example"
#执行结果
10 #返回的结果为字符串tcltk在字符串中第一次出现的子字符串第一个字符的索引
5 #从4这个索引开始搜索is
2
如果使用了 -exact
选项,匹配会变得严格,即只有在大小写和字符顺序都完全匹配的情况下才会返回匹配位置。如果省略 -exact
,则匹配是大小写不敏感的。
string last ?substring string ?last?
与first命令相似,只是返回的是最后搜索到的匹配的字符段,lastIndex含义也有所不同,first命令中的index指定了从index往后搜索,而这里是从index往前。
代码如下(示例):
string last "is" "This is a tcltk example"
string last "is" "This is a tcltk example" 3
#执行结果
5 #返回的is不是This中的is
2
string index str charIndex
返回字符串中索引为charIndex的字符,字符串的索引从0开始。
代码如下(示例):
string index "This is a tcltk example" 14
#执行结果
k
string is class ?-strict? ?-failindex varname? str
判断字符串类型,如果string是指定class中的成员就返回1,否则返回0。如果指定了-strict,空字符串就返回0,不指定则返回1。如果指定了-failindex,那么将导致不匹配的索引储存在varname中,如果返回1则varname不会被赋值。
代码如下(示例):
# 判断字符串是否是小写字母构成的字符串
string is lower "This"
string is lower "this"
#执行结果
0
1
string map -nocase? mapping str
根据mapping表里面的key-value关系替换str中的子字符串,mapping是一个类似于key-value key-value …的列表,每个在str中的key都会被value替换。如果指定了-nocase,匹配就不需要考虑差别。key和value都可以是多字符的,置换按照一定的顺序进行,所以在列表前面的key会被优先置换。
代码如下(示例):
string map {abc 1 ab 2 a 3 1 0} 1abcaababcabababc #mapping为abc-1 ab-2 a-3 1-0 str为1/abc/a/ab/abc/ab/ab/abc
string map {1 0 ab 2 a 3 abc 1} 1abcaababcabababc #mapping为1-0 ab-2 a-3 abc-1str为1/ab/c/a/ab/ab/c/ab/ab/ab/c
#执行结果
01321221 #str只会被置换一次,所以前面做过置换操作的字符将不匹配后面的key,
02c322c222c #如果前面的key是后面一个key的前缀,那么就会全部匹配前面的key,后面的key不会被匹配
string match $str1 $str2
字符串str1和字符串str2匹配返回1,不匹配返回0,字符串str1是模式匹配字符串,str2是待匹配的。模式匹配字符串就是可以包含特殊字符(具有特殊的含义)的字符串,特殊字符如下。
代码如下(示例):
# 使用大括号包括整个参数,来避免出现变量置换或者分隔符等一些问题,[6-81A-Z]表示匹配6,7,8,1,A,B,C,D,...X,Y,Z
string match {a*[6-81A-Z]xyz\*} abcd6xyz*
string match {a*[6-81A-Z]xyz\*} abcd7xyz*
string match {a*[6-81A-Z]xyz\*} abcd8xyz*
string match {a*[6-81A-Z]xyz\*} abcd1xyz*
string match {a*[6-81A-Z]xyz\*} abcdAxyz*
string match {a*[6-81A-Z]xyz\*} abcdFxyz*
string match {a*[6-81A-Z]xyz\*} abcdZxyz*
#执行结果
1
1
1
1
1
1
1
string range str first last
返回str中从first到last指定索引范围内的所有字符。first和last指定索引,如果first小于0则按照0来处理,如果last大于或者等于字符串长度则按照end来处理,如果first大于last则返回空字符串。
代码如下(示例):
string range "This is a tcltk example" 1 14
#执行结果
his is a tcltk
string repeat str count
返回一个把str重复count次的字符串。
代码如下(示例):
string repeat "This" 3
#执行结果
ThisThisThis
string replace str first last ? newstring?
也很简单,使用newstring替换string中的first到last的字符串,如果没有newstring,就是使用空代替。
代码如下(示例):
string replace "This is a tcltk example" 10 14 TCLTK
#如果没有newstring
string replace "This is a tcltk example" 10 14
#执行结果
This is a TCLTK example
This is a example
string reverse str
返回string的反序字符串。
代码如下(示例):
string reverse "This is a tcltk example"
#执行结果
elpmaxe ktlct a si sihT
string tolower str ? first? ? last?
将一个字符串全部变为小写形式。first和last指定了转换的范围。
代码如下(示例):
string tolower "This is a tcltk example"
#执行结果
this is a tcltk example
string totitle str ? first? ? last?
将一个字符串全部变为大写形式。
代码如下(示例):
string toupper "This is a tcltk example"
#执行结果
THIS IS A TCLTK EXAMPLE
string toupper str ? first? ? last?
将一个字符串里面开头的第一个字母转换为大写形式,其他字符转化为小写形式。
代码如下(示例):
string totitle "this is a TCLTK example"
#执行结果
This is a tcltk example
string trim str ? chars?
去掉chars字符,如果没有指定chars字符,则去掉空白符(包括空格符、制表符、换行符、回车符)。trim对字符串开头和结尾都操作。
代码如下(示例):
string trim "!!This is a tcltk example!!" !
#执行结果
This is a tcltk example
string trimleft str ? chars?
去掉chars字符,如果没有指定chars字符,则去掉空白符(包括空格符、制表符、换行符、回车符)。ttrimleft只对字符串开头操作。
代码如下(示例):
string trimleft "!!This is a tcltk example!!" !
#执行结果
This is a tcltk example!!
string trimright str ? chars?
去掉chars字符,如果没有指定chars字符,则去掉空白符(包括空格符、制表符、换行符、回车符)。trimright只对字符串结尾操作。
代码如下(示例):
string trimright "!!This is a tcltk example!!" !
#执行结果
!!This is a tcltk example
string wordend str charIndex
wordend是找出给定索引的字符所在的单词的下一个单词的第一个字符的索引。
代码如下(示例):
string wordend "This is a tcltk example" 12
#执行结果
15 #12索引为tcltk中的l字符,那么返回的结果就是l所在的词tcltk的下一个词example中的第一个字符e的索引,即15
string wordstart str charIndex
wordstart是找出给定索引的字符所在的单词的第一个字符的索引。
代码如下(示例):
string wordstart "This is a tcltk example" 12
#执行结果
10 #12索引为tcltk中的l字符,那么返回的结果就是l所在的词的第一个字符t的索引,即10
2. regexp
语法:regexp ?switchs? ?–? exp string ?matchVar?\ ?subMatchVar subMatchVar…?
regexp 命令用于判断正规表达式 exp 是否全部或部分匹配字符串 string,结构为regexp + {表达式} + 待匹配文本,匹配返回 1,否则 0。为了将匹配到的字符串存储在变量里,regexp 还可以接多个变量名,用来存储一个一个的子串,结构为regexp + {表达式} + 待匹配文本 + Allmatch + subMatch1 + subMatch 2 + … , Allmatch为正则表达式匹配的结果。
正则表达式用于匹配字符串,包含字符和元字符。元字符包括^、$、.、*、+、?、[]、()、|等。常见用法:
匹配任何单个字符: .
匹配除换行符外的任意单个字符。例如:a.b 可以匹配 aab, acb, a1b 等。
匹配开始和结束:^ 和 $
^ 表示字符串开始,$ 表示字符串结束。例如:^a 匹配以 a 开头的字符串,b$ 匹配以 b 结尾的字符串。
字符集合:[]
匹配括号内的任意一个字符。例如:[abc] 匹配 a, b, c 中的任意一个字符。
字符范围:-
在字符集合中,- 表示范围。例如:[a-z] 匹配任何小写字母。
字符组:()
用于分组。例如:(ab|cd) 匹配 ab 或 cd。
匹配零个或多个字符:*
匹配零个或多个前面的字符。例如:a* 匹配零个或多个 a。
匹配一个或多个字符:+
匹配一个或多个前面的字符。例如:a+ 匹配一个或多个 a。
匹配零个或一个字符:?
匹配零个或一个前面的字符。例如:a? 匹配零个或一个 a。
代码如下(示例):
set text "Hello, World!"
if {[regexp {Hello} $text]} {
puts "文本中包含 'Hello'。"
}
#执行结果
文本中包含 'Hello'。
set text "The cat sat on the mat."
if {[regexp {cat.*mat} $text]} {
puts "文本中包含 'cat' 和 'mat' 之间的任意字符。"
}
#执行结果
文本中包含 'cat' 和 'mat' 之间的任意字符。
set text "My email is example@email.com"
if {[regexp {email is (.*)} $text match email]} {
puts "邮箱地址是:$email"
}
#执行结果
邮箱地址是:example@email.com #正则表达式{email is (.*)}匹配了文本中 "email is " 后面的任意字符,并将其保存在捕获组中,然后通过$email来获取,$match为email is example@email.com,$email为{email is (.*)}中(.*)匹配的结果
set text "Today is 2024-05-24"
if {[regexp {(\d{4}-\d{2}-\d{2})} $text match date]} {
puts "日期是:$date"
}
#执行结果
日期是:2024-05-24 #正则表达式{(\d{4}-\d{2}-\d{2})}匹配了文本中的日期格式,并将其保存在捕获组中,$match为2024-05-24,$date也为2024-05-24
# Match the first two words, the first one allows uppercase
set sample "Where there is a will, There is a way."
set result [regexp {([A-Za-z]+) +([a-z]+)} $sample match sub1 sub2 ]
puts "Result: $result\nallMatched: $match\nfirstMatched: $sub1\nsecondMatched: $sub2"
# 执行结果
Result: 1
allMatched: Where there
firstMatched: Where
secondMatched: there
#([A-Za-z]+):这个部分匹配一个或多个大写或小写英文字母。括号 () 表示这是一个捕获组,可以单独提取这部分匹配的内容。A-Za-z 覆盖了所有的英文大写和小写字母,+ 量词表示至少有一个字母;空格+:这个部分匹配一个或多个空格字符。+ 号紧跟在空格后面,表示空格至少出现一次,用于分隔两个单词;([a-z]+):这个部分匹配一个或多个小写英文字母。同样,括号表示这是另一个捕获组,可以单独提取这部分匹配的内容。a-z 覆盖了所有的英文小写字母,+ 量词表示至少有一个字母
3. regsub
语法:regsub ?switchs? exp string subSpec varname
regsub 的第一个参数是一个整个表达式,第二个参数是一个输入字符串,这一点和 regexp 命 令完全一样,也是当匹配时返回 1,否则返回 0。不过 regsub 用第三个参数的值来替换字符串 string 中和正规表达式匹配的部分,第四个参数被认为是一个变量,替换后的字符串存入这个 变量中。
代码如下(示例):
regsub {there} “they live there lives” their x #正则表达式为 there ,匹配字符串中的单词 there,将其替换为 their,并将替换后的字符串存入变量 x, 返回 1,所以变量 x 的值就是 $x="they live their lives"
注意 regsub 有个选项 -all,如果没有这个开这个选项,则只替换第一个匹配, 否则替换所有匹配到的目标。
4. format
语法:format formatstring ?vlue value…?
format 命令类似于 ANSIC 中的 sprintf 函数和 MFC 中 CString 类提供的 Format 成员函数。 它按 formatstring 提供的格式,把各个 value 的值组合到 formatstring 中形成一个新字符串, 并返回。例如:
代码如下(示例):
set name john
输出:John
set age 20
输出:20
set msg [format "%s is %d years old" $name $age]
输出:john is 20 years old
5. scan
语法:scan string format varName ?varName …?
scan 命令可以认为是 format 命令的逆,其功能类似于 ANSI C 中的 sscanf 函数。它按 format 提供的格式分析 string 字符串,然后把结果存到变量 varName 中,注意除了空格和 TAB 键之 外,string 和 format 中的字符和’%'必须匹配。例如:
代码如下(示例):
scan "some 26 34" "some %d %d" a b
输出:2
set a
输出:26
set b
输出:34
scan "12.34.56.78" "%d.%d.%d.%d" c d e f
输出:4
puts [format "the value of c is %d,d is %d,e is %d ,f is %d" $c $d $e $f]
输出:the value of c is 12,d is 34,e is 56 ,f is 78
scan 命令的返回值是匹配的变量个数。而且,如果变量 varName 不存在的话,TCL 会自动声明该变量。