TCLScriptingFundamentalsTCL快速入门上手指导演示教学_第1页
TCLScriptingFundamentalsTCL快速入门上手指导演示教学_第2页
TCLScriptingFundamentalsTCL快速入门上手指导演示教学_第3页
TCLScriptingFundamentalsTCL快速入门上手指导演示教学_第4页
TCLScriptingFundamentalsTCL快速入门上手指导演示教学_第5页
已阅读5页,还剩73页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Good is good, but better carries it.精益求精,善益求善。TCLScriptingFundamentalsTCL快速入门上手指导ContentsTOCo1-3hzuHYPERLINKl_Toc1760831991.WWWHAboutTCLPAGEREF_Toc176083199h-4-HYPERLINKl_Toc1760832001.1.WhatisTCLPAGEREF_Toc176083200h-4-HYPERLINKl_Toc1760832011.2.WhyTCLPAGEREF_Toc176083201h-4-HYPERLINKl_Toc176083202

2、1.3.WhenshallweuseTCLPAGEREF_Toc176083202h-5-HYPERLINKl_Toc1760832031.4.HowtoprogramusingTCLPAGEREF_Toc176083203h-5-HYPERLINKl_Toc1760832042.TCLBasicsPAGEREF_Toc176083204h-6-HYPERLINKl_Toc1760832052.1.VariablesandSubstitutionPAGEREF_Toc176083205h-6-HYPERLINKl_Toc1760832062.1.1CommandsetandunsetPAGER

3、EF_Toc176083206h-6-HYPERLINKl_Toc1760832072.1.2CommandappendPAGEREF_Toc176083207h-6-HYPERLINKl_Toc1760832082.1.3CommandincrPAGEREF_Toc176083208h-7-HYPERLINKl_Toc1760832092.2.MathExpressionsPAGEREF_Toc176083209h-7-HYPERLINKl_Toc1760832102.2.1GeneralMathExpressionsPAGEREF_Toc176083210h-7-HYPERLINKl_To

4、c1760832112.2.2MathFunctionsPAGEREF_Toc176083211h-8-HYPERLINKl_Toc1760832122.3.StringManipulationPAGEREF_Toc176083212h-9-HYPERLINKl_Toc1760832132.3.1CommandstringPAGEREF_Toc176083213h-9-HYPERLINKl_Toc1760832142.3.2CommandformatPAGEREF_Toc176083214h-14-HYPERLINKl_Toc1760832152.3.3RegularExpressionPAG

5、EREF_Toc176083215h-16-HYPERLINKl_Toc1760832162.4.ListManipulationPAGEREF_Toc176083216h-20-HYPERLINKl_Toc1760832172.4.1BasicTCLListCommandsPAGEREF_Toc176083217h-20-HYPERLINKl_Toc1760832182.4.2AdvancedTCLListCommandsPAGEREF_Toc176083218h-22-HYPERLINKl_Toc1760832192.5.FileOperationsPAGEREF_Toc176083219

6、h-25-HYPERLINKl_Toc1760832202.5.1CommandopenPAGEREF_Toc176083220h-25-HYPERLINKl_Toc1760832212.5.2CommandfilePAGEREF_Toc176083221h-28-HYPERLINKl_Toc1760832222.6.ControlFlowPAGEREF_Toc176083222h-31-HYPERLINKl_Toc1760832232.6.1TheifcommandPAGEREF_Toc176083223h-31-HYPERLINKl_Toc1760832242.6.2LoopingandL

7、oopControlcommandsPAGEREF_Toc176083224h-32-HYPERLINKl_Toc1760832253.TCLextensionsPAGEREF_Toc176083225h-34-HYPERLINKl_Toc1760832263.1.TCLPackageExpectPAGEREF_Toc176083226h-34-HYPERLINKl_Toc1760832273.2.TCLPackageTnmPAGEREF_Toc176083227h-35-HYPERLINKl_Toc1760832284.AppendixPAGEREF_Toc176083228h-38-HYP

8、ERLINKl_Toc1760832294.1.AppendixA,StringCommandsPAGEREF_Toc176083229h-38-HYPERLINKl_Toc1760832304.2.AppendixB,ListCommandsPAGEREF_Toc176083230h-39-HYPERLINKl_Toc1760832314.3.AppendixC,FlowControlCommandsPAGEREF_Toc176083231h-40-HYPERLINKl_Toc1760832324.4.AppendixD,MathFunctionsPAGEREF_Toc176083232h-

9、40-HYPERLINKl_Toc1760832334.5.AppendixE,ReferencesPAGEREF_Toc176083233h-41-WWWHAboutTCL本文是针对那些对TCL没有或者有一些基础认识的测试工程师,这个标题中的WWWH并不是一个英文单词,而是一个缩写,这个缩写所提出的问题也基本上是本文所要提出并解决的问题;他们分别是What什么是TCL、Why为什么要使用TCL、When什么时候我们该使用TCL、How如何使用TCL。如果您读到这里觉得这四个问题已经很清楚了,那么此文对您意义不大,不必再浪费时间阅读;如果您对其中的一个或者多个问题仍存有疑惑,也许本文能帮助你找

10、到一些您需要的答案。.WhatisTCL在开始认识任何事物之前,我们首先要弄清楚的一件事情就是它到底是什么,做什么用的;学习TCL之前也一样,我先来了解一下TCL到底是什么。TCL的缩写是ToolCommandLanguage,它是一种解释性的脚本语言,TCL以及它的图形界面工具包Tk最早是由美国加州大学伯克利分校(UniversityofCalifornia,Berkeley)的JohnK.Ousterhout教授设计完成的。需要注意的是TCL的两大定位:第一,它是脚本语言;第二,它是解释性的语言。那么什么又是脚本语言,什么又是解释性的脚本语言呢?大多数有工科背景的读者应该知道,计算机是不能

11、直接读懂或者执行高级计算机语言的,计算机只能识别机器码,CPU通过机器码从内存中读取并执行相应的指令。所以高级计算机语言要被计算机识别和运行必须进行一项翻译工作,将高级计算机语言翻译成为机器能读懂的机器语言。有的高级语言在完成编写之后,将翻译这个工作交给编译器来完成,编译器将高级的计算机语言根据预先约定好的规则翻译成机器码,并生成一个机器能识别的可执行文件,经典的程序语言C就是这样的一种高级计算机语言,我们称之为编译性语言。有的语言,在完成编写之后,省略掉翻译这个过程,它不需要编译器来帮助它完成转换。那么机器又是如何读懂这类语言的呢?这种语言,在执行的时候通过自身的解释器进行翻译,也就是说解释

12、器在执行代码的时候才会将其逐行转换成为机器能识别的机器码,从而达到执行的目的。知道了前面的这些信息之后,相信大家会明白,原来这种语言的源文件和编译性语言的源文件是不同的。编译性语言的源文件在完成编译之后就没有用了,没有这个源文件,机器只需要编译后的可执行文件就能完成相应的操作;可解释性语言的源文件在执行过程中才被翻译,在执行过程中还是必须的,这也就是为什么我们称之为脚本(script)语言。读到这里,相信您对解释性脚本语言以及TCL有了个大概的认知,知道了它是什么,那么接下来我就要去问,为什么要用TCL而不用别的解释性脚本语言呢?选择使用TCL有什么好处呢?.WhyTCL在这一小节我们将探讨一

13、下为什么在我们的测试工作中使用解释性脚本语言,以及为什么我们要在测试中使用TCL的脚本而不是其他的解释性脚本语言。本文假定读者对于通信设备的测试工作已经有了基本的认识,所以对于自动化测试的重要性以及自动化测试在测试方法学中的相关理论部分,在本文中不再冗叙。在繁重枯燥的测试工作中,使用计算机语言来编写自动化脚本是提供工作效率、缩短测试周期的重要手段和途径。那么为什么我们要选择TCL这种语言而不选择其他的脚本语言呢?事实上,目前有多种流行的脚本语言,TCL只是其中的一种而已,例如VB、Python、Perl等等;脚本语言在很多行业有着广泛的应用,在通信设备行业中,TCL是众多厂商的共同选择,有很多

14、世界级的通信设备制造商更是有着很高程度的脚本自动化测试;更为重要的是,通信设备测试仪器仪表厂商对于TCL的支持,是大部分通信设备厂商在测试中采用TCL作为自动化测试脚本语言的根本原因之一,例如SpirentSmartbits,IXIA等测试仪器都是支持TCL脚本驱动的。当然脚本语言的无需编译,顺序可执行以及错误处理机制都是脚本语言适用于自动化测试的根本原因,由于这些属于脚本语言的共性,在此就无须冗叙了。.WhenshallweuseTCL前面花了一些篇幅来介绍TCL是什么以及为什么要使用TCL,那么您也许比较疑惑,既然脚本语言如此高效,那么是不是把测试工作全部由脚本来实现就好了呢?只要编写好测

15、试脚本,测试工作就会自动完成,测试工程师们也就可以高枕无忧了。如果老板们也是这么想的,那么很不幸,大部分的测试工程师也许都要失业了。事实上,自动化在测试工作中只是多种测试方法和测试途径之一,自动化测试绝对不是万能的从而取代手工测试的。那么作为一个测试工程师,到底该在什么时候使用TCL编写自动化脚本来实现自动化测试呢?总体来说,那些繁琐的机械化的且耗费很多人力的测试比较适合用脚本来实行自动化测试,把测试工程师从繁琐枯燥的重复劳动中解放出来从而能将精力放在一些更加复杂的测试中去。下面列举一些使用TCL开发自动化脚本之前需要考虑的因素,供读者参考:使用TCL开发的自动化脚本应该是由功能性测试(Fun

16、ctiontesting)阶段和回归测试(Regressiontest)阶段的需求而驱动编写的,在一些常用的应用场景测试中也可以开发一些重复利用率高的TCL脚本;开发的自动化脚本必须是有较高的重复利用率,如果花很多精力编写一个只会用一两次的脚本是得不偿失的;开发的自动化脚本必须是可读性高的,易于维护的,并且能提供信息收集能力的脚本,一个无法提供错误信息反馈的脚本对于测试是没有价值的;并不是所有的功能测试与回归测试都能通过自动化脚本来完成,当开发一个脚本所需要的精力大大超过手工测试的精力时,要避免使用脚本测试;以上列举出来只是一些基本的需要考量的因素,读者可以根据自身的工作情况灵活决定脚本的开发

17、。有了上面的信息,我们可以开始了解TCL这个脚本语言了,也就是如何使用TCL。.HowtoprogramusingTCL在后续的几章节,会重点从变量、数学运算、字符串操作、正则表达式、列表操作、文件操作等几个方面来介绍TCL,通过阅读上述几个方面的内容能对TCL的编写规则以及内嵌命令有初步的了解并能动手编写出一些简单常用的TCL脚本。TCLBasics.VariablesandSubstitution在TCL中,变量可以是单个字符/数字,也可以是字符串,也可以是列表或者是数组。总体来说,TCL中涉及到的常用的变量替换以及操作命令有四个:set、unset、append和incr。Command

18、setandunsetTCL命令set是用来定义变量(字符/数字、字符串、列表、数组),而unset则是用来删除变量的,set与unset互为逆操作。%seta10;#定义变量a并赋值数字1010%setab;#定义变量a并赋值字符bb%setaHelloWorld!;#定义变量a并赋值字符串”HelloWorld!”HelloWorld!%seta12345;#定义变量a并赋值列表1234512345%setarr(a)1;#定义数组arr并赋值arr(a)数字11通过上面的例子读者应该很容易看出TCL中的变量定义以及赋值的规律,而unset就是set的逆操作,unseta就是删除变量a。C

19、ommandappend命令append的作用是将字符或者字符串直接添加到原变量值的末尾。%seta0;#定义变量a并赋值数字00%appendax0800;#添加字符串”x0800”到a的尾部0 x0800%setb;#定义变量b为空字符串%appendbABC;#添加字符串”ABC”到b的尾部ABC%appendbD;#添加字符”D”到b的尾部ABCDCommandincr命令incr的作用是对变量的值进行增量操作,默认增量为1,但是操作对象仅对于整数。%seta100;#定义变量a并赋值100100%incra;#使用默认增量对a作增量操作101%incra100;#对a的值增量1002

20、01%incra-101;#对a的值增量-101100在这里顺便介绍一下incr的一个小技巧,灵活使用incr命令可以达到数制转换的目的,可将八进制或者十六进制的数转换为十进制整数。%seta0 x0800;#定义变量a并赋值十六进制数0 x08000 x0800%incra0;#对a的值作0增量达到数制转换的目的2048%setb0126;#定义变量b并赋值八进制数01260126%incrb0;#对b的值作0增量达到数制转换的目的86.MathExpressions和其他的高级计算机语言一样,TCL也提供了强大的数学运算功能。TCL解释器本身不支持对数学运算表达式的求值,所有的运算都是通过

21、TCL内嵌命令expr来实现的。TCL中的大部分数学运算符与C语言类似。在这里必须强调的一点是任何的数学表达式都必须通过expr来实现,否则是无法被TCL解释器处理的。%1+2;#没有使用expr命令的数学表达式invalidcommandname1+2%expr1+2;#使用了expr命令的数学表达式3GeneralMathExpressions对于大家熟知的加减乘除就不再介绍了,运算符和C是一样的;下面通过例子来看看几个常用的数学表达式:逻辑与、逻辑或与选择表达式。注意逻辑与的运算符是&,逻辑或的运算符是|。%seta11%setb00%expr$a&$b;#逻辑与运算0%expr$a|$

22、b;#逻辑或运算1通过上面的例子细心的读者会发现在进行逻辑与和逻辑或运算的时候变量前面都有一个$符号,这个符号代表变量的值。例如a代表变量的名字,而$a代表的是变量的值,在上面的例子中,$a等于1。注意在TCL的数学运算中是值之间进行运算,所以在表达式中要使用变量值,而不是变量名。下面再通过一个例子来看一下选择表达式,选择表达式的基本格式为:expr($a$b)?$a:$b;基本功能是括号中的表达式成立的话则选择a的值,否则选择b的值。%seta1010%setb2020%setcexpr($a$b)?$a:$b;#判断条件成立选择a的值赋给c10%setcexpr($a返回值为-1,0和1;

23、分别代表小于、等于和大于;stringequalstring1string2=返回值为1和0;分别代表相等与不相等;注意stringcompare命令的返回值代表的小于和大于是按照英文字母表中的顺序来的,原则是小写字母大于大写字母,字母表顺序越靠后的大于顺序靠前的,也就是aZA的顺序,下面通过几个例子来看一下stringcompare/stringequal的基本功能:%stringcompareabcxyz-1%stringcompareabcABC1%stringcompareABCABC0%stringequalabcABC0%stringequalabcabc1除去stringcomp

24、are与stringequal在命令功能上的不同,这两个命令在关键字扩展使用上又有着很多的相同。例如,两个命令都可以用-nocase关键字在字符串比较的时候忽略字符串的大小写差异;两个命令都可以用-lengthn关键字在字符串比较时只比较前n个字符。通过下面的例子读者可以对关键字的使用有更直观的认识:%stringcompare-nocaseabcABC0%stringequal-nocaseabcABC1%stringcompare-length3abcxyzabcdef0%stringequal-length4abcdmnabcdpq1%stringcompare-nocase-lengt

25、h3AbCdefaBcxyz0%stringequal-nocase-length2XYacbdxyzabc1.Stringmatching字符串操作的另一个常见的操作是字符串的匹配,我们通常需要知道某个或某些未知字符串中是否有我们所需要的或感兴趣的某个字符或者部分字符串。TCL中做字符串匹配最常用的命令是stringmatch,该命令有很大的使用灵活度,用户可以通过指定不同的匹配条件来检查字符串的匹配情况。下面我通过stringmatch命令的基本格式和几个例子来了解它的使用方法;其命令基本格式为:stringmatchpatternstring%stringmatchABC*ABCdefg

26、1%stringmatchabc*ABCdefg0%stringmatchABC?ABCd1%stringmatchABC?ABCdefg0%stringmatch-nocaseabc*ABCdefg1%stringmatch*.a-zmath.h1%stringmatch?.0-9a-zA-Zm.01%stringmatch?.0-9a-zA-Zm.jar0%stringmatch?.0-9a-zA-Zmath.h0通过上面的例子,我可以对于stringmatch命令总结出以下几点使用规律:1)、匹配条件中使用“*”指匹配一个或多个字符;2)、匹配条件中使用“?”指匹配单个字符;3)、该命令

27、同样支持区分大小写的关键字-nocase;4)、该命令支持使用字符的匹配范围定义;需要指出的是stringmatch中对于匹配条件支持了字符范围的定义,但在使用时一定要注意命令的格式,匹配条件必须用“”括起来,而范围必须用“”括起来。Stringmatch命令的这一特性使得字符匹配操作的灵活性大大提升,可是它还是局限于比较简单的字符匹配,如果有更加复杂的字符匹配的,就需要使用功能更为强大的正则表达式了。关于正则表达式,会在后面章节专门作介绍。%stringfirstabc0 xabc579abcd58%stringfirstabc0 xabc579abcd02除了stringmatch之外,还

28、有两个较为常用的TCL字符/字符串匹配命令:stringfirst和stringlast。这两个命令的功能比较接近,都是在被匹配字符串中以指定的索引号来查找匹配字符串所出现的索引号,只是前者是查找第一次出现的索引号,而后者是查找最后一次出现的索引号。这两句话读起来会比较拗口一些,如果难以理解,我们通过一些例子就很容易明白是怎么回事了。我们来结合上面的例子来理解一下stringfirst命令是怎么使用的。在例子中,字符串“abc”叫做匹配字符串,而后面的“0 xabc579abcd”是被匹配的字符串;稍做观察便可以得知,在被匹配的字符串中包含两处“abc”,也就是例子中的匹配字符串,那么第一个例

29、子最后的那个5又代表什么意思呢?5指的是序列索引,也就是说从被匹配字符串从左向右数,以0为起点的第五个字符处开始做匹配,查找匹配字符串“abc”第一次出现的索引数,读者可以自己数一下,在第一行的例子中,后面第二次出现的“abc”是不是以零为起点的第八个字符处出现的。在第二行的例子中,匹配索引号是0,也就是说从被匹配字符串的最左边开始进行匹配查询,那么很显然匹配字符“abc”第一次出现在以零为起点的第二个字符处。那么stringlast又是怎么使用的呢?注意!stringlast和stringfirst在匹配索引号的意义上是完全不一样的!在stringlast中,索引号代表的意思是从被匹配字符串

30、的最左端起到索引号所制定的字符处,在这段被指定的范围内来查找匹配字符串最后出现的索引号。我们通过例子来理解:%stringlastabc0 xabc579abcd0-1%stringlastabc0 xabc579abcd52%stringlasta0a23456789abcdef1510%stringlasta0a23456789abcdef91上面例子中的第一行,匹配索引号为0,即范围是空的,也就是说根本没有匹配,所以返回值是“-1”,通过这个例子读者可以发现当stringfirst和stringlast根本没有匹配的时候返回值是多少;同样的匹配字符串和被匹配字符串,在第二行的例子中可以看

31、到,由于匹配索引号为5,那么匹配检查区间是被匹配字符串的最左边开始到以零为起点的第五个字符处,即“0 xabc5”。在这个区间中最后一次出现匹配字符串是在以零为起点的第二个字符处,所以返回值是“2”。第三行与第四行的例子希望读者自己根据上述的规律去读懂以加深理解。下面总结出stringfirst与stringlast的命令基本格式,注意,这两个命令不像前面介绍的命令那样支持区分大小写开关,这两个命令是不支持-nocase关键字的:stringfirstsubStringstring?startIndex?stringlastsubStringstring?startIndex?.Stringp

32、rocessing我们再来看看TCL中的字符串处理。在测试工作中,我们经常需要将从设备得到的信息或反馈加以分析和处理,得到我们所需要的有价值的信息;在编写脚本对设备进行自动化测试时,字符串的处理就是经常会使用的操作之一,在这一小节我们来了解几个简单常用的字符串处理命令,并通过例子来说明他们的使用方法。首先我们来了解一下命令stringlength。这个命令的作用是以字符数目为单位输出字符串的长度,例如字符串“abcd”的长度就是4,字符串“gh%#9kl”的长度是7。该命令的基本格式为:stringlengthstring。通过简单的例子来看一下它的使用方法:%stringlengthieuw

33、rds9*%&11接下来我们来了解下stringrepeat。该命令的作用在于重复输出n个用户指定的字符或字符串,通过下面的例子来加深理解:%stringrepeat=20=%stringrepeat-SOS-10-SOS-SOS-SOS-SOS-SOS-SOS-SOS-SOS-SOS-SOS-再来看看两个互为逆操作的字符串输出命令:stringtoupper和stringtolower。前一个命令是将待输出的字符串全部以大写输出,而后面一个则是全部以小写输出:%stringtoupperabc123XYZABC123XYZ%stringtolowerabc123XYZabc123xyz然后是

34、返回字符串中的特定位置的单个字符的命令stringindex:%stringindexabcdefg1b%stringindexabcdefg10%stringindexabcdefg0a%stringindexabcdefg-1%可以通过上面的例子看出,stringindex命令中的索引号也是以零为起点的,如果索引号超过字符串的长度或者是非法数值,命令将不会返回任何结果。上面的stringindex只能输出字符串中指定位置的单个字符,如果需要输出多个字符怎么办呢?TCL中有一个命令是提供了这个功能的:stringrange;请读者根据下面的例子对照stringindex理解stringran

35、ge的用法。%stringrangeabcdefg03abcd%stringrangeabcdefg010abcdefg%stringrangeabcdefg00a%stringrangeabcdefg0-1%最后介绍的这几个命令,都是将字符串根据用户需求进行编辑之后再输出的,他们是stringtrim/trimleft/trimright和stringreplace。先来看看stringtrim命令及其扩展命令stringtrimleft/stringtrimright。总体来说,这三个命令都是将字符串中的单个或者多个字符去掉再输出;stringtrimleft是左端去除字符而stringt

36、rimright是右端去除字符。%stringtrimabccbaabccb%stringtrimabccbababccba%stringtrimabccbacabccba%stringtrimleftabccbaabccba%stringtrimrightabccbaaabccb%stringtrimabccbaaabccba%stringtrimabccbaabccba%stringtrimrightabccbaabccba%stringtrimleftaaaabccbaaaaabccbaaaa%stringtrimaaaabccbaaaaabccb%stringtrimabccbaabc

37、c%stringtrimleftabccbaabccba%stringtrimrightabccbaababcc从上面的例子可以看出,stringtrim/stringtrimleft/stringtrimright都只能去除字符串两端的单个或多个字符。如果要去除的字符不指定的,命令会默认去掉字符串两端/左端/右端的空格;如果字符串两端并没有所指定要去除的字符或字符串,则输出原始字符串。以上介绍的只是string命令中一些常见的较简单的用法,读者可以在本文最后的推荐书籍中找到更多关于string命令的用法以及扩展。Commandformat与C语言中的sprintf函数功能一样,TCL中的fo

38、rmat命令使用户能灵活的输出格式化字符串;用户可以根据需要使用format命令及其关键字对待输出字符串做格式处理并加以输出。使用format命令重点在于使用正确的关键字,在这部分内容中会介绍4种常用的format命令关键字:整数到ASCII码转换关键字c、字符串输出关键字s、浮点数输出f、十六进制数输出关键字x/X。通过下面的几个例子读者能进一步理解format命令的用法:%format%c%c%c%c%c97112112108101apple%format%sThisisatextstringThisisatextstring%format%fexprpow(2,3)8.000000%fo

39、rmat%x%X1515fF由上面的几个例子不难发现format命令的关键字之前都必须使用标识符“%”;读者也许会发现其他的三个关键字都对原来的字符或字符串做了改变输出,但是字符串关键字s却没有任何改变。我们通过下面的例子来学习如何灵活使用字符串关键字s:%format%20s%5sTestResultFAILTestResultFAIL%format%-20s%5sTestResultPASSTestResultPASS%format%-20s%-5sTestResultPASSTestResultPASS默认情况下TCL将格式化字符串右端对齐输出,上面第一个例子给第一个格式化字符串定义了2

40、0个字符的空间,而字符串“TestResult”只用到了11个字符空间,所以在输出的格式化字符串时左端会有9个空格;在第二个例子中第一个格式化字符串关键字前面多了一个“-”号,这个符号就是用来调整格式化字符串输出左端对齐的,右端对齐的控制符是“+”,由于默认就是右端对齐,所以第二个字符串关键字前面没有加任何控制符。在第三个例子中读者应该可以发现第二个字符串关键字s前也加了左端对齐控制符“-”,但是为什么输出的结果中“PASS”只比第二个例子中的“PASS”左移了一个字符呢?不是应该左端对齐的么?这里需要注意的是字符串格式化输出所定义的空间大小,第二个字符串定义的是5个字符,输出字符串“PASS

41、”或者“FAIL”都只占用了4个字符空间,所谓的左端对齐是按照定义的空间向左对齐,这就是为什么第三个例子中的“PASS”会比第二个中的左移了一个字符的空间;而第一个格式化输出的“TestResult”左对齐之后将9个空格空间加在了字符串尾部,再加上格式定义中的两个字符串间的空格,才成了我们看到的结果中的两个字符串之间的间距。有了格式化输出,那又如何做格式化字符串输入呢?TCL中还支持一个format的逆操作命令scan。由于scan命令与format的关键字等都一样,就不再花篇幅介绍了,下面给出一个例子读者自己读懂并加深理解:%procNEXTcharscan$char%ciformat%ce

42、xpr$i+1%NEXTab%NEXTxyRegularExpression在前面讲到stringmatch命令的时候提到过TCL正则表达式,正则表达式的可读性比较差,但是功能却很强大。正则表达式主要的功能就是字符串匹配与替换操作,常用的命令有两个:regexp与regsub;匹配成功表达式返回值为1,否则返回0。首先我们来通过一个例子来看看正则表达式到底是怎么样的:%regexp(0 x)?0-9a-fA-F+$0 x08001上面的例子已经充分说明了正则表达式是可读性很差的,为了灵活的使用正则表达式,我们先来读懂正则表达式。正则表达式中会有一个或者多个操作符,代表了一个或者多个匹配条件,下

43、面列出的是正则表达式最常见的操作符及其代表的意义:1)、“”;匹配字符串首部;2)、“$”;匹配字符串尾部;3)、“*”;零个或者多个匹配;4)、“+”;一个或者多个匹配;5)、“?”;选择性匹配;6)、“|”;多个表达式判断逻辑合并;在这些操作符中首先要掌握的就是首尾匹配操作符,例如“abc”指匹配任何以“abc”开头的字符串,“abc$”则指匹配任何以“abc”结尾的字符串;而“abc$”则指严格匹配字符串“abc”。请读者参考下面的例子:%regexpabcabcdefg1%regexpabcabdcefg0%regexpabc$xyzabc1%regexpabc$xyzabk0%reg

44、expabc$abc1%regexpabc$ABC0请读者注意在书写正则表达式的时候建议将匹配条件表达式用“”括起来,与被匹配字符串区分开来,这只是书写上加强易读性的建议,并非语法的严格定义。通过上面的几个例子读者应该已经掌握了字符串首尾匹配操作符的使用方法了,接下来我们继续通过例子来学习三个匹配范围操作符的用法:%regexpabca-z*abc1%regexpabca-z+abc0%regexpabca-z+abcd1%regexpabca-z*abcd1%regexpabc*ab1%regexpabc*abc1%regexpabc*abcccc1%regexpabc+ab0%regexp

45、abc+abc1%regexpabc+abcccc1由上面的一组例子可以总结出匹配操作符“*”和“+”的使用方法;前者代表零个或者多个匹配,后者代表一个或多个匹配。再来通过几个例子来看看选择性匹配操作符是怎么使用的:%regexp(TCL)?abc+$TCLabccc1%regexp(TCL)?abc+$abccc1%regexp(TCL)abc+$abccc0%regexp(TCL)abc+$TCLabccc1通过上面的例子可以发现选择性匹配操作符一般配合“()”使用,当然如果是单个字符也可以不使用括号,但是建议在书写正则表达式的时候统一将选择性匹配字符串使用括号括起来加强易读性。之所以被称

46、为选择性匹配操作符,是由于允许被匹配的字符串中可以包含也可以不包含选择性匹配的部分。读到这里读者们应该对TCL的正则表达式有了个初步的认识,需要加强理解和记忆的是正则表达式的几个匹配操作符,由这几个简单的匹配操作符可以写出很多灵活的匹配条件,注意,目前为止我们讲的正则表达式的例子都是正向匹配,其实通过首部匹配符“”也是可以实现排他性的反向匹配的,下面的几个例子就是介绍首部匹配符在匹配作用域中的应用:%regexp45a-g45d1%regexp45a-g45d0%regexp45a-g45z1我们再来通过例子学习下匹配操作符“|”的作用:%regexp(0 x)?0-9a-fA-F+$|0-9

47、+$0 x08001%regexp(0 x)?0-9a-fA-F+$|0-9+$20461%regexp(0 x)?0-9a-fA-F+$|0-9+$0 xxyz0%regexp(0 x)?0-9a-fA-F+$|0-9+$xyz0上面的几个例子中的正则表达式的作用是匹配任意的十六进制或十进制数,在例子中,匹配操作符“|”将两个匹配条件连接成了一个表达式,形成了一个并列的多判断条件的表达式。在逐个了解了匹配操作符的作用之后,我们通过几个综合的例子来巩固一下用regexp命令书写的正则表达式,请读者结合前面的讲解认真读懂下面的每个例子:%regexp(0 x)?0-9a-fA-F+$0 x080

48、01%regexp(0 x)?0-9a-fA-F$0 x08000%regexp(0 x)?0-9a-fA-F$0 x01%regexp(0 x)0-9a-fA-F+$08000%regexp(0 x)?0-9a-fA-F+$08001%regexp(0 x)?0-9a-fA-F+$0 x0%regexp(0 x)?0-9a-fA-F*$0 x1%regexp(0 x)?0-9a-f+$0 xFFFF0%regexp-nocase(0 x)?0-9a-f+$0 xFFFF1细心的读者会发现原来regexp命令也是支持nocase关键字的。不仅如此,regexp命令书写的正则表达式还有给变量赋值

49、的功能,当表达式的被匹配字符串后面还跟有字符,会被当作变量处理,如果正则表达式匹配成功,会将被匹配字符串赋给这些变量,我们通过一个例子来说明:%regexp-nocase(a-z+)*(0-9+)*(a-z+)Walk10kmabcd1%puts$a;$b;$c;$drWalk10km;Walk;10;km上面的例子中表达式的判定条件是以一个由字母组成的字符串开头,在零个或多个空格后接上一个十进制数字,又在零个或多个空格之后再接上一个由字母组成的字符串。被匹配字符串“Walk10km”是符合表达式的判定条件的,所以表达式返回值为1;注意在被匹配字符串之后还有4个字符,这4个字符就被当做了变量(

50、注意只有当表达式匹配成功返回值为1时变量才会被赋值)。那么正则表达式是以什么规则给变量赋值的呢?由上面的例子我们可以总结出赋值的规律:紧跟在被匹配字符串后的第一个变量会被赋值整个被匹配字符串;第二个变量会被赋值表达式中第一个匹配条件所匹配的字符串部分;第三个变量会被赋值表达式中第二个匹配条件所匹配的字符串部分,依此类推。当变量数目大于表达式匹配条件数目加一,则多出的变量会全部被赋值为空字符串。例如上面的例子如果再有一个变量e,那么e的值将是空字符串,读者可以自己结合上面的例子练习一下,体会正则表达式的赋值功能。关于使用regexp命令书写的正则表达式字符串匹配内容在这里就告一段落,希望读者认真

51、读懂所给出的每一个例子,最好自己再加以练习,正则表达式由于其易读性较差,所以在书写的时候更是要逻辑清晰条理清楚。下面我们来学习TCL正则表达式中的第二个常用的命令,用于字符串替换赋值操作的regsub命令。与regexp命令不一样,regsub命令的作用在于替换操作并赋值;首先通过一个例子来看看regsub命令是如何使用的:%regsubthereTheylivetherelivestheirx1%puts$xTheylivetheirlives由上面的例子可以看出regsub命令用被替换字符串去匹配被匹配字符串并将匹配到的字符串替换成新的替换字符串;然后将新的字符串赋值给变量。其命令格式为:

52、regsub?switches?expstringsubSpec?varName?注意regsub如果匹配失败返回0,最后的变量仍旧会被赋值,其值是被匹配字符串不做任何替换修改直接赋值给变量。从regsub命令的格式中可以看出它是支持一些关键字的,例如nocase大小写的关键字以及常用的关键字-all等。下面通过例子来看看关键字-all的使用方法:%regsuba-zA-Z+TheylivetherelivesN/Ax1%puts$xN/Alivetherelives%regsub-alla-zA-Z+TheylivetherelivesN/Ax4%puts$xN/AN/AN/AN/A%reg

53、sub-nocasea-z+TheylivetherelivesN/Ax1%puts$xN/Alivetherelives%regsub-nocase-alla-z+TheylivetherelivesN/Ax4%puts$xN/AN/AN/AN/A除了以上的用法之外,regsub命令还支持一些特殊的替换操作符,例如“&”和“0”。这两个替换操作符的作用是一样的,都是将匹配到的字符或字符串替换成匹配字符或字符串本身。这些替换操作符的使用并不常见,读者根据下面例子能读懂就可以了。%regsub-alla|bacaab&x4%puts$xaacaaaabb%regsub-alla|bacaab&x

54、4%puts$xacaab%regsub-alla|bacaab00 x4%puts$xaacaaaabb到这里,基本的TCL的字符串操作就介绍完了,在这一部分中,读者应该通过学习重点掌握字符串操作命令string及其扩展命令、会使用format命令格式化输出字符串、能读懂基于regexp和regsub的正则表达式并能写一些简单的正则表达式。目前为止我已经给读者们介绍了TCL中最重要的操作之一字符串操作,在接下来的一个部分里,我们将重点介绍TCL的另一个重要的基本操作列表操作。.ListManipulation正如前文中所提到的一样,列表操作是TCL中另一类重要的操作,在这一章节中,我将结合实

55、例介绍最常用的TCL列表命令及其使用方法。BasicTCLListCommands在这一部分,我们主要学习如何创建一个列表以及如何取得列表的相关信息,以及如果做最基本的列表操作。那么首先,什么是列表?所谓的列表是零个或多个元素的集合;当列表元素个数为零时,我们称之为空列表。列表的元素没有严格的限制,可以是数字,也可以是字符串,也可以是子列表;或者是上述几个的组合。对于一个已知或未知的列表,我们最关心的问题是列表中是否有元素、列表中元素的个数、列表中元素的类型或者列表中某个特定的元素是什么等等。首先我们需要知道的是如何创建一个列表,通过前面的学习,大部分读者也许会想到set命令。的确,set命令

56、可以用来创建一个列表;但是TCL还有另外一个命令能够用来创建列表,那就是list命令。那么这两个命令有什么区别呢?区别在于set命令必须将列表本身赋值给变量,而list命令的作用只在创建列表,而不赋值给任何变量。我们通过例子来理解这两者的区别。%seta1234512345%list1234512345%set12345cantread12345:nosuchvariable%setalist1234512345从上面的例子中读者应该可以发现创建列表的两个方法了,他们所达到的效果是一样的。那么如何创建一个没有元素的空列表呢?有时候我们需用通过进一步的操作才能确定列表中的所有元素,然后将元素放到

57、列表中去。这种情况下,用户可以选择较为灵活的方式来创建空的列表,请参考下面的例子:%seta%setb%setclist%puts$a%puts$b%puts$c%上面的三个方法都可以达到创建空列表的目的,有的读者也许会问上面例子中的第一个和创建空的字符串有什么区别。答案是没有区别,这就是个人认为TCL的优点之一,你可以创建一个变量,它的值是空,你用字符串命令对这个变量做操作那么这个变量就变成字符串变量;你对它用列表命令操作它就变成了字符串变量,非常的灵活。但是,为了增强脚本的可读性,创建空变量时建议使用上面例子中的第二个。知道了如何创建一个列表,接下来我们就要关注一下我们所感兴趣的内容了,对

58、于一个未知的或已知的列表,我们通常需要得到一些确切的信息,例如:这个列表的长度/元素个数有多少、这个列表中的任意一个元素是什么等等。有的读者也许会质疑,为什么已知的列表却还要关心其长度或任意一个元素呢?举个例子,你用列表来记录学校报道新生的名字,可能今天大概有500多个学生来报道,那么每个学生的名字都是确定输入的,但是当你完成所有输入之后如何快速的统计出列表中学生名字的个数呢?当然如果保证不出错的话,用数是可以的。幸运的是,TCL中提供了一些命令,让我们获取列表的相关信息。下面介绍两个命令:llength和lindex。细心的读者会发现这两个命令都是以字母“l”开头后面接着一个有意义的英文单词

59、,这个“l”代表list,也就是代表这个命令是列表操作命令,大部分的TCL列表操作命令都有这个特征。命令llength是用来取一个列表的长度的,也就是列表中的元素个数;命令lindex是用来将列表中的特定位置的元素取出来。需要注意的是lindex命令在取列表中元素时其使用的索引号是0-base的。什么意思呢?举个例子来说,一个列表中有5个元素,我们用lindex命令取其中第一个元素,那么使用lindex命令时索引号应该是多少呢?应该是0,如果取第二个元素,那么索引号就应该是1;如果取第n个元素,索引号就应该是n-1。请读者们注意,如果是刚刚开始使用列表命令时是很容易搞混淆的,经常会直接把索引号

60、写成要取的元素的排列号。通过下面的例子来进一步理解lindex与llength的使用方法。%setaABCDEFGABCDEFG%llength$a7%lindex$a0A%lindex$a1B%lindex$a7%请注意最后一个例子就是典型的错误,之前通过llength命令取得了列表的长度为7,也就是有7个元素,那么我们想取第7个元素,就应该将lindex命令的索引号写成6,请牢记索引号n-1的规律。在学习了如何创建列表以及取得列表的基本信息之后,我们再来学习一下简单的列表操作,这一部分介绍3个相关的命令:lappend、split和join。其中lappend命令是用来将单个元素添加入列表

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论