目录
5.2 取字符:string index 和 string range
string index "hello world" 0
输出:h
string range "hello world" 6 end-1
输出:worl
- 索引从0开始
- end对应结尾
- 可以使用表达式,如
end-$i
5.3 长度、大小写转换、裁剪、重复
- 长度:
string length "hello world"
输出:11
- 大小写转换:
string toupper "Hello World"
(小写:string tolower
)
输出:HELLO WORLD
- 裁剪
- 匹配两端:
string trim "abcxxxcba" ab
输出:cxxxc
- 匹配左边:
string trimleft "abcxxxcba" ab
输出:cxxxcba
- 匹配右边:
string trimright "abcxxxcba" ab
输出:abcxxxc
- 匹配两端:
- 重复:
string repeat "hello world" 2
输出:hello worldhello world
5.4 简单搜索
从左到右搜索字符串中第一个wo
的首字符位置,找不到返回-1
:
string first wo "hello worldhello world"
输出:6
指定从索引为10的字符开始搜索:
string first wo "hello worldhello world" 10
输出:17
string last
: 从右到左搜索
5.5 字符串比较
string compare "hello" "Hello"
输出:1
string compare "Hello" "hello"
输出:-1
string compare "Hello" "Hello"
输出:0
忽略大小写:string compare -nocase "Hello" "hello"
输出:0
设置比较的长度:string compare -length 1 "hELLO" "hello"
输出:0
只返回0(不相同)或1(相同):string equal -nocase -length 2 "hello" "Hexxx"
输出:1
5.6 字符串置换
string replace
string replace "hello world" 6 10 "Tcl"
输出:hello Tcl
- 参数
6 10
被替换字符串索引的起始与结束。 - 参数
Tcl
:可以省略,结果等效为删除。
- 参数
string map dictionary string
将string中出现的的所有dictionary关键字置换为相应的值。
输出:set entities { action1 hello action2 learn name Tcl } string map -nocase $entities {Action1 name,action2 name}
hello Tcl,learn Tcl
5.7 确定字符串类型
string is type string
类型 | 描述 |
---|---|
Alnum | 全为Unicode字母或数字 |
alpha | 全为Unicode字母 |
ascii | 全为7位ASCII字符 |
boolean | 布尔型值(0、false、no、off、1、true、yes、no) |
control | 全为Unicode控制字符 |
digit | 全为Unicode数字 |
double | 双精度浮点(忽略前后空白字符) |
false | 布尔型值非 |
graph | 全为非空白Unicode打印字符 |
integer | 32位整型 |
list | 一个有效的列表结构。如果结构不正确,-failindex变量会设置为列表中第一个导致结构无效的元素 |
lower | 全为Unicode小写字母 |
全为Unicode打印字符(含空白) | |
punct | 全为Unicode标点符号 |
space | 全为Unicode空白符号 |
true | 布尔型值是 |
upper | 全为Unicode大写字母 |
wideinteger | 长整型 |
wordchar | 全为字母和连接符 |
xdigit | 全为16进制数 |
string is 命令用Unicode规定测试字符,例如 Unicode的数字字符就不止ASCII字符的0~9
5.8 用format创建字符串
Tcl的format命令提供与ANSIC库中的sprintf程序相似的功能。
format "1 + 1 = %.3f" [expr {1+1}]
输出:1 + 1 = 2.000
Tcl中format命令的重要性不如C中的printf。printf和sprintf为了把二进制数值转换为字符串,从而进行字符串替换操作。但是Tcl的值本来就以字符串存储。
常用用途:
- 改变一个值的格式,以改善显示效果。
format "exp(%d) %12.3f" 9 [expr exp(9)]
输出:exp(9) 8103.084
- 改变一个值的表现形式。数值->ASCII。
format "int:%d ASCII:%c" 97 97
输出:int:97 ASCII:a
5.9 用scan解析字符串
scan 待解析字符串 解析格式 存储解析结果的变量
返回完成转换的次数
% scan "name: w0shishabi, age: 22" "name: %10s, age: %f" name age
2
% set name
w0shishabi
% set age
22.0
5.10 通配符样式的模式匹配
string match命令:string match ?-nocase? pattern string
% string match w* w0shishabi
1
通配符含义:
字符 | 说明 |
---|---|
* | 零个或多个任意字符 |
? | 一个任意字符 |
[chars] | 与[chars]中的任意一个字符匹配。 |
\x | 转义符号,与单个字符x匹配 |
5.11 使用正则表达式进行模式匹配
-
分类
- 基本正则表达式(BRE)
- 拓展正则表达式(ERE)
- 高级正则表达式(ARE),Tcl8.1以上支持
-
正则表达式的原子(元字符)
正则表达式模式的基本单位称为原子。
正则表达式中的特殊字符:字符 说明 . 任意单个字符 ^ 指定与输入字符串开头匹配 $ 指定与输入字符串结尾匹配 \m 与单词开头匹配 \M 与单词结尾匹配 \k 匹配非字母非数字的字符k \c 转义,当c是字母或数字,用c替换\c [chars] chars范围: a-b
。与chars中的任意单个字符匹配。如果chars第一个字符是^
,则与非chars字符匹配。如果chars第一个字符是]
,或者~
出现在chars的开头或结尾,则被当作文本处理。(regexp) 匹配正则表达式regexp * 与0个或多个前述原子组成的序列匹配 + 与1个或多个前述原子组成的序列匹配 ? 与空字符串或前述一个原子匹配 {m} 前述原子组成的序列匹配正好m次 {m,} 前述原子组成的序列匹配至少m次 {m,n} 前述原子组成的序列匹配至少m次,至多n次 re1|re2|… 与任意一个正则表达式匹配 正则表达式中的字符-条目转义序列
转义序列 表示的内容 \a 铃声、警报声、字符 \b 退格 \B 反斜线 \
\cX 取给定字符X的低5位,高位补0作为转义后的字符 \e 转义字符 \f 换页 \n 换行 \r 回车 \t 制表符 \uwxyz 由给定的十六进制数指定的Unicode字符 \v 垂直制表符 \xhhh 由给定的十六进制数指定的ASCII码字符 \0 空、零、字符 \xyz 由给定的两位或三位八进制数给定的ASCII码字符 圆括号中的正则表达式组成的原子:如
(a,b)
。方括号表示的范围的原子:
1. 字符范围:如[^0-9a-fA-F]
表示与不含十六进制字符的字符串匹配。
2. 字符类型:如[:alpha:]
表示全部字母。正则表达式中的字符类型
类型 说明 [:alpha:] 字母 [:alnum:] 字母和数字 [:blank:] 空格和制表符 [:cntrl:] 控制字符 [:digit:] 十进制数字 [:graph:] 有图形的字符,如数字、字母或标点 [:lower:] 小写字母 [:print:] [:graph:]加空白符 [:punct:] 标点符 [:space:] 空白符 [:upper:] 大写字母 [:xdigit:] 十六进制数字 字符类型的简写
|转义序列|表示的类型|
|\d|[[:digit:]]|
|\D|[1]|
|\s|[[:space:]]|
|\S|[2]|
|\w|[[:alnum:]]|
|\W|[3]| -
正则表达式的分支和量词
- 分支
- 正则表达式可以用操作符
|
连接。 - 用
|
连接起来的正则表达式称为分支。 - 分支可以用
()
括起来避免太长。
- 正则表达式可以用操作符
- 量词
- 操作符
*、+、?
以及边界{}
指定重复次数,称为量词。
如^(0x)?[0-9a-fA-F]+$
匹配十六进制数。 - 量词默认是 贪婪(尽可能多的匹配) 的,后面加一个
?
变成非贪婪的。
- 操作符
- 分支
-
逆向引用
就是将匹配到的字符用于模式中。
如:([ab])\1
与字符串aa
和bb
匹配,与ab
和ba
不匹配,因为逆向引用\1
将第一个匹配到的字符a
或b
用于模式中。 -
非捕获子表达式
用于不需要对子表达式进行逆向引用或者解析的情况,特点是速度快。
格式:(?:expression)
-
regexp命令
作用:调用正则表达式匹配。% regexp {^(0x)?[0-9a-fA-F]+$} 0x5a 1
注意:建议总是把正则表达式括在大括号中,避免出发变量替换或命令替换。
5.12使用正则表达式进行替换
`regsub 模式 字符串 替换字符串 替换后的接受字符串`
```
% regsub there "they live there lives" their x
1
% set x
they live their lives
```
5.13 二进制字符串
命令:binary format formatString ?arg arg ...?
- binary format命令在一个Tcl变量中创建二进制字符串。
- formatString 由一系列字段指示符组成,可以包含分隔符,描述要格式化的数据的类型,还可能给出需要格式化的条目数(默认为1),
*
表示各项都要格式化。
% binary format c3 {65 66 67}
ABC
返回一个二进制字符串
字段指示符c3
表示格式化3个8位有符号整数。