|
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
索引
Tcl 语言
Tcl 基础
脚本, 命令, 和字(word)Tcl 是基于字符串的解释型命令语言。它在语法上的简单性和语义上的通常的感官性的方式(common sensical approach)使这门语言易于学习和熟练。这个简短的教程将集中于最基本的概念,使你能尽快的起步。Tcl 脚本由一个或多个命令组成,用换行或分号分隔。 command arg1 arg2 arg3 ... 命令是基本的执行单元(element)。一个命令跟随着一个或多个字,这些字是(命令)参数(parameters or arguments), 字之间用空格或 tab 分隔。 ex: puts stdout "My first Tcl script." 求值(Evaluating)一个命令两步过程: 分析和执行。 注意: 参数在缺省时是被引用的 --
如果你想求值,你必须显式的提出要求 set a 5 第一条命令把字符串 5 赋给变量 a。第二条命令把字符串 a+8 作为新值存储在 b 中。要得到值 13,你必须显式的去求值,比如: set a 5 每对方括号调用一次附加的求值。对于 Tcl 你必须记住的一件事是它只做你认为它将要做的事。求值的模型很直接了当。有一个单独的命令和零或多个参数。这些参数可以依次是必须被求值的有参数的命令。这些命令的返回值变成要被求值的最初的命令的参数。
变量,命令和反斜线替换在 Tcl 中通过使用变量来维护状态,变量用 "set" 命令来声明和实例化(instantiate)。 例如: set loopCounter 0 注意分开的变量声明是没有必要。使用美元标号来检索变量值,这对 shell 程序员和 Perl 开发者是很熟悉的,在何时使用与何时不使用美元标号的相关规则上有细微的区别。 例如: if 引用和注释变量简单变量 有一个名字和一个值(被作为一个字符串存储)。 数组是一组元素(element),每个元素有它自己的名字和值。数组名和元素名可以是任意的字符串 (有时叫做关联数组 来与要求元素名是整数的数组相区别)。 例如: set yearTotal 0 Tcl 只实现了一维数组,但是多维数组可以通过通过连接多个索引成一个单一的元素名来模拟。 set matrix(1,1) 140 * 注意这里没有空格,三个元素名是 1,1 、1,2 和 1,3。 所以: matrix(2,5) matrix(2, 5) 表达式
表达式组合操作数和操作符来建立一个新值。 语法: expr arg ?arg arg ...? 操作符替换对于表达式操作数替换以两种方式发生。 例如: expr { 2*sin($x) } 花括号致使 Tcl 分析器不做对 x 做变量替换。当变量求值器遇到美元号的时候,它自己完成变量替换。这对 expr 命令是非常有用的,而且对其他的象 while 这样的的命令也是有用的, while 重复的求一个表达式的值并希望每次都有不同的结果。 例如: set pow 1 while {$pow<$num} { set pow [expr $pow*2] } 如果省略了{$pow<$num} 的花括号,while 的参数将是一个不变的表达式如 1<44,这将导致无限的循环。 字符串操纵Tcl 允许一些操作符有字符串操作数,如: <、 >、<=、>=、 == 和 != 。对所有其他的操作符,操作数必须是数值。如果一个或两个操作数不能做数来分析,Tcl 将使用字符串比较。 例如: set x 0 set y 00 if {$x==$y} { ... } 将使用算术比较并且这个测试将求值成 1。要强制对数值操作数进行字符串比较,使用象 string compare 这样的命令。 类型和转换Tcl 求表达式的值尽可能的得出数值。只对一个或两个操作数不象是数值的关系操作符进行字符串操作。对有着不同类型的操作数自动进行转换:
还有,分别的使用 double、int 和 round 来转换 int 成 real 和转换 real 成 int。 精度
列表译注:在 Tcl 中用一对问号表示其中的部分是可选的,在其他语言的语法描述中这项任务通常用方括号完成。 一个列表是一组有序的元素(用空格分隔),每个元素都可以有任意的字符串值。列表可以是嵌套的。
控制流
过程过程是在一个可以重用的包装模块中的通常的 Tcl 命令。在任何时候都可以定义过程,并可以用传值或传引用来传递参数。除非显式的使用 return 命令返回,否则返回的值是过程体的最后一条语句的结果。 语法: proc procedure_name arguments ?args? body 例子: proc plus {a b} {expr $a+$b} 参数在一个过程中使用的参数是本地的。要引用全局变量,在过程的生存期间 global 命令在过程中绑定变量(译注:就是访问全局变量)。参数可以有缺省值并象下面这样指定: proc inc {value {increment 1}} { 如果有的话,缺省的参数必须是过程的最后一个参数。如果没指定一个缺省则要求有这个参数。 用 args 来支持可变数目的参数,它被放在参数列表的最后。过程使用 args 参数作为一个列表,它的每个元素都是额外的参数。如果没有额外的参数,则设置 args 为空串。 proc sum args { 引用调用upvar 命令提供一个访问一个过程上下文外部的变量的通用机制。可被用于访问在一些其他的活跃的过程中的全局或本地变量,但它最常用于传递数组(因为没有数组的值,只有数组的元素)。 例子: proc parray name { upvar 也可以被用于访问在调用栈的不同层次上的变量。 upvar #0 other x 通过本地变量 x 来使全局变量 other 可访问(#0 指定访问全局变量 other 而不管调用栈的层次)。 upvar 2 other x 使在当前的过程的调用者的调用者中的变量 other 作为本地变量 x 访问(2 指定在调用栈中两层之上)。 建立新的控制结构uplevel 是一个 eval 和 upvar 之间杂交的命令。它象 eval 那样把它的参数作为一个脚本来求值,但象 upvar 那样在一个不同的栈层次的变量上下文中求脚本的值。使用 uplevel,可以定义作为 Tcl 过程的一个新的控制结构。 例子: proc do {varName first last body}{ 象 upvar 一样,uplevel 接受一个可选的初始参数来指定一个显式的栈层次。 字符串操纵Tcl 是完全 8 位的(不只是 ASCII 7 位子集)。Tcl 不为 ASCII 子集外的字符提供任何解释。Tcl 存储字符串使用一个 null (零)字符作为终结,所以不可能在字符串中存储零字符。要表示二进制数据,要把它转换成包括非零字符的形式,例如,把字节转换成相应的十六进制的值。 通配符-式样(Glob-style)模式匹配Tcl 模式匹配的最简单的形式。 语法: string match pattern string 匹配则返回 1,不匹配返回 0。在匹配中使用特殊的字符串
用正则表达式的模式匹配正则表达式可以有多层的结构。基本的建造块叫做原子,并且最简单的正则表达式的形式由一个或多个原子组成。一个正则表达式要匹配一个输入字符串,输入中必须有一个子串(substring),每个正则表达式的原子(或其他成分)匹配子串的相应的部分。例如,正则表达式 abc 匹配包含 abc 的任何字符串比如 abcdef 或 xabcy。 举个例子,下面的模式匹配要么是十六进制数要么是十进制数的任何字符串。 ^((0x)?[0-9a-fA-F]+|[0-9]+)$ 语法: regexp ?-nocase? ?-indices? {pattern} input_string ?variable ...? 如果没有匹配则返回 0,如果有一个匹配则返回 1。 注意,模式必须被包裹(enclosed)在花括号中,这样字符 $、[、和 ] 可以被传递给(pass through to) regexp 命令而不触发变量或命令替换。 如果调用 regexp 有在输入字符串之后的参数,每个参数都被作为一个变量的名字对待。第一个变量被添入匹配整个正则表达式的子串。第二个变量被添入与模式中最左的圆括号中的(parenthesized)子表达式(subexpression)相匹配的子串的相应的部分,第三个变量被添入匹配下一个子表达式并以次类推。如果有变量名比圆括号中的子表达式多,则额外的变量被设置成空串。 例子: regexp {([0-9]+) *([a-z]+)} "Walk 10 km" a b c 变量 a 将被持有值 "10 km", b 将持有 "10" 而 c 将持有 "km"。 开关 -nocase 指定匹配大小写不敏感。开关 -indices 指定增加的变量不应被添入匹配的子串的值,而是给出在输入字符串中子串的范围的最先和最后的索引的一个列表。 例子: regexp -indices {([0-9]+) *([a-z]+)} "Walk 10 km"a b c 变量 a 将被持有值 "5 9",b 将持有 "5 6" 而 c 将持有 "8 9"。
为替换而使用正则表达式语法: regsub ?-nocase? ?-all? pattern input_string replacement_value new_string 给 regsub 的第一个参数是正则表达式模式。如果在输入字符串中发现一个匹配,regsub 返回 1, 否则它返回 0 (同于 regexp 命令)。如果模式被匹配,输入字符串中的子串被用第三个参数所替换并且新串被存储在第四个参数中。如果没发现匹配,第四个参数包含原始的输入串。使用了两个开关: -nocase 等价于 regexp 命令的 nocase 开关, -all 导致在输入串中所有匹配的子串都被替换。 格式化输出format 命令提供了象 ANSI sprintf 那样的设施。 例子: format "The square root of 10 is
%.3f" [expr exp(10)] 其他的格式指定符(specifier):
格式化命令也被用于改变一个值的代表。例如,用 %c 格式化一个整数生成这个整数代表的 ASCII 字符。 用 scan 分析字符串语法: scan parse_string format_string ?variable ...? 例子: scan "16 units, 24.2 margin"
"%d units, %f" a b 字符函数字符串操纵命令是 string 命令的选项。 string index "See Spot run." 5 string range "See Spot run." 5 8 string range "See Spot run." 5
end 查找和比较用 first 或 last 查找一个子串返回子串的第一个字符的位置(以 0 开始,对应输入串中第一个字符以)。如果没发现匹配则返回 -1。 string first th "The trains were thirty
minutes late this past week" string last th "The trains were thirty
minutes late this past week" 如果串匹配 Compare 返回 0 ,如果第一个比第二个排序在前返回 -1, 如果第一个比第二个排序在后返回 1。 string compare twelve thirteen string compare twelve twelve 长度, 大小写转换, 修剪(trimming)string length "not too long" string toupper "Hello, World!" string tolower "You are lucky winner
13!" string trim abracadabra abr string trim 接受一个要修剪的字符串和可选的一组修剪字符,并且从它的参数字符串的开头和结尾删除所有的修剪字符的实例,返回修剪后的字符串作为结果。trimleft 和 trimright 选项除了只是在字符串的开头或结尾删除之外,以相同的方式工作。trim 命令最常用于删除额外的白空格,如果没指定修剪字符,它们的缺省是白空格(空格、tab、换行、回车、和 form feed)。 资源上面的许多例子取自 John Ousterhout 的书: 尽管有许多关于 Tcl 语言的书,依我看这本书是最好的之一。
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
原文出处: http://jan.netcomp.monash.edu.au/ProgrammingUnix/tcl/tcl_tut.html 原文作者:William Ho bill@technologyarchitects.com 中文译者: 寒蝉退士 |
|
©Tcl/Tk中文网 2003-2008 |
|