第6章文本 MATLAB真正强有力的地方在于它的数值处理能力。然而,经常希望操作文本,例如 把标号和标题放在图上。在 MATLAB里,文本当作特征字符串或简单地当作字符串。 6.1字符串 在 MATLAB中的字符串一般是ASCI值的数值数组,它作为字符串表达式进行显示。 例如 >)t= how about this character strins How about this character string ))size(t) > whos Size Elements Bytes Density Complex I by 2 Ful 个字符串是由单引号括起来的简单文本。在字符串里的每个字符是数组里的一个元 素,字符串的存储要求每个字符8个字节,如同 MATLAB的其它变量。因为ASCI字符只 要求一个字节,故这种存储要求是浪费的,7/8所分配的存储空间无用。然而,对字符串保 持同样的数据结构简化 MATLAB的内部数据结构。所给出的字符串操作并不是 MATLAB 的基本特点,但这种表达是方便和可接受的 为了了解下面字符串的AsCⅡ表达,只需对字符串执行一些算术运算。最简单和计算 上最有效的方法是取数组的绝对值。例如, 》u=abs(t Columns I through 12 7211l1193297981l117116 116104 Columns 13 through 24 1051153299104971149799116101114 Columns 25 through 32 3211511611410511010363
第 6 章 文 本 MATLAB 真正强有力的地方在于它的数值处理能力。然而,经常希望操作文本,例如 把标号和标题放在图上。在 MATLAB 里,文本当作特征字符串或简单地当作字符串。 6.1 字符串 在 MATLAB 中的字符串一般是 ASCII 值的数值数组,它作为字符串表达式进行显示。 例如, » t=' How about this character string? ' t = How about this character string? » size(t) ans = 1 32 » whos Name Size Elements Bytes Density Complex ans 1 by 2 2 16 Full No t 1 by 32 32 256 Full No 一个字符串是由单引号括起来的简单文本。在字符串里的每个字符是数组里的一个元 素,字符串的存储要求每个字符 8 个字节,如同 MATLAB 的其它变量。因为 ASCII 字符只 要求一个字节,故这种存储要求是浪费的,7/8 所分配的存储空间无用。然而,对字符串保 持同样的数据结构简化 MATLAB 的内部数据结构。所给出的字符串操作并不是 MATLAB 的基本特点,但这种表达是方便和可接受的。 为了了解下面字符串的 ASCII 表达,只需对字符串执行一些算术运算。最简单和计算 上最有效的方法是取数组的绝对值。例如, » u=abs(t) u = Columns 1 through 12 72 111 119 32 97 98 111 117 116 32 116 104 Columns 13 through 24 105 115 32 99 104 97 114 97 99 116 101 114 Columns 25 through 32 32 115 116 114 105 110 103 63
7211111932979811111711632116104 Columns 13 through 24 1051153299104971149799116101114 Columns 25 through 32 3211511611410511010363 在上面后一个例子里,加零到字符串也改变了它的ASCⅡ的表示。函数 setstr提供了逆 转换 tr(u) 因为字符串是数值数组,它们可以用 MATLAB中所有可利用的数组操作工具进行操作 u=t(16:24) 字符串象数组一样进行编址。这里元素16到24包含单词 character 这是单词 character的反向拼写 u=(16:24)
» u=t+0 u = Columns 1 through 12 72 111 119 32 97 98 111 117 116 32 116 104 Columns 13 through 24 105 115 32 99 104 97 114 97 99 116 101 114 Columns 25 through 32 32 115 116 114 105 110 103 63 在上面后一个例子里,加零到字符串也改变了它的 ASCII 的表示。函数 setstr 提供了逆 转换。 » v=setstr(u) v = How about this character string? 因为字符串是数值数组,它们可以用 MATLAB 中所有可利用的数组操作工具进行操作。例 如, » u=t(16:24) u = character 字符串象数组一样进行编址。这里元素 16 到 24 包含单词 character » u=t(24:-1:16) u = retcarahc 这是单词 character 的反向拼写。 » u=t(16:24)' u = c h a r a c t e
用转置算子将单词 character变换成一个列 v=I can t find the manual! I can't find the manual 字符串内的单引号是由两个连续的单引号来表示。 字符串连接可以直接从数组连接中得到 ))UF If a woodchuck could chuck wood ))v= how much wood would a woodchuck chuck? w=[uⅥ If a woodchuck could chuck wood how much wood would a woodchuck chuck 函数dsp允许不打印它的变量名而显示一个字符串。例如 If a woodchuck could chuck wood 注意u=语句被去掉了。这对脚本文件内显示帮助的文本有用。 如同矩阵,字符串可以有多个行,但每行必须有相同数目的列数。因此,显然要用空格 以使所有行有相同长度,例如 >)V=l Character strings having more than of column just like matrices Character strings having more than one row must have the same number 考虑下面例子,它把一个字符串转换成大写。首先,函数fnd用来找出小写字符的下 标值,然后,从小写元素中只减去小写与大写之差,最后,用 setstr把求得的数组转换成它 的字符串表示。 If a woodchuck could chuck wood
r 用转置算子将单词 character 变换成一个列。 » v=' I can''t find the manual! ' v = I can't find the manual! 字符串内的单引号是由两个连续的单引号来表示。 字符串连接可以直接从数组连接中得到。 » u=' If a woodchuck could chuck wood, ' ; » v=' how much wood would a woodchuck chuck? ' ; » w=[u v] w = If a woodchuck could chuck wood, how much wood would a woodchuck chuck? 函数 disp 允许不打印它的变量名而显示一个字符串。例如, »disp(u) If a woodchuck could chuck wood, 注意 u = 语句被去掉了。这对脚本文件内显示帮助的文本有用。 如同矩阵,字符串可以有多个行,但每行必须有相同数目的列数。因此,显然要用空格 以使所有行有相同长度,例如, » v=[' Character strings having more than ' ' one row must have the same number ' ' of column just like matrices! '] v = Character strings having more than one row must have the same number of column just like matrices! 考虑下面例子,它把一个字符串转换成大写。首先,函数 find 用来找出小写字符的下 标值,然后,从小写元素中只减去小写与大写之差,最后,用 setstr 把求得的数组转换成它 的字符串表示。 » disp(u) If a woodchuck could chuck wood
>)i=find(u>=a'&u)u(i=setstr(u(1)-(a'-A)) IF A WOODCHUCK COULD CHUCK WOOD 事实上,如在37节所描述的,矩阵能由单个下标标识。而不是由行和列下标标识,所 以上面例子对字符串矩阵ⅴ也同样适用 Character strings having more than one row must have the same number of column just like matrices >i=find(v>=a&v)V(i)=setstr(v(i)-(a'-A)) o and matrix keeps the same orientation CHARACTER STRINGS HAVING MORE THAN ONE ROW MUST HAVE THE SAME NUMBER OF COLUMN JUST LIKE MATRICES! 最后,当使用前面脚本文件这一章节中的函数 input时,字符串是很有用的 >)t Enter num ber of rolls of Enter number of rolls of tape >5 另外,函数 input能输入一个字符串 >)xinput( Enter anything>, s) Enter anything >anything can be entered anything can be entered 这里,在函数 input里的附加参量’s告诉 MATLAB,作为一个字符串,只要把用户输 入传送到输出变量,就不需要引号。事实上,如果将引号包括进去,它们就变成返回字符串
» i=find(u>=' a ' & u=' a ' & v ' ; » tape=input(t) Enter number of rolls of tape > 5 tape = 5 另外,函数 input 能输入一个字符串: » x=input(' Enter anything > ',' s ') Enter anything > anything can be entered x = anything can be entered 这里,在函数 input 里的附加参量’s’告诉 MATLAB,作为一个字符串,只要把用户输 入传送到输出变量,就不需要引号。事实上,如果将引号包括进去,它们就变成返回字符串 的一部分
6.2字符串转换 除了上面讨论的,字符串和它的ASCI表示之间转换外, MATLAB还提供了大量的其 它的有用的字符串转换函数。它们包括: 表6.1 字符串转换 字符串到ASC转换 十进制数到十六进制字符串转换 In 把格式化的文本写到文件中或显示屏上 Xae 十六进制字符串转换成十进制数 hex2num 十六进制字符串转换成IEEE浮点数 int2str 整数转换成字符串 字符串转换成小写 num2str 数字转换成字符串 setstr ASCII转换成字符串 用格式控制,数字转换成字符串 sscanf 用格式控制,字符串转换成数字 str2mat 字符串转换成一个文本矩阵 str num 字符串转换成数字 字符串转换成大写 在许多情况下,希望把一个数值嵌入到字符串中。几个字符串转换可完成这个任务。 >>rad=2.5; area=pi"rad 2 >t=[' A circle of radius num2str(rad)has an area of num2str(area)',' disp(t) A circle of radius 2.5 has an area of 19.63 这里函数num2str用来把数值转换成字符串,字符串连接用来把所转换的数嵌人到 个字符串句子中。按类似方式,int2str把整数转换成字符串。无论是num2str还是int2str 都调用函数 sprint,它用类似C语言语法把数值转换成字符串 函数 fprintf经常是函数disp的一个有用替换,由于它提供了对结果更多的控制。当准 备把格式化的数据写到一个文件中去时,按缺省它在命令窗口显示结果。例如 >)fprintf( See what this does) See what this doess >)fprintf( See what this doesn See what this does
6.2 字符串转换 除了上面讨论的,字符串和它的 ASCII 表示之间转换外,MATLAB 还提供了大量的其 它的有用的字符串转换函数。它们包括: 表 6.1 字 符 串 转 换 abs 字符串到 ASCII 转换 dec2hex 十进制数到十六进制字符串转换 fprintf 把格式化的文本写到文件中或显示屏上 hex2dec 十六进制字符串转换成十进制数 hex2num 十六进制字符串转换成 IEEE 浮点数 int2str 整数转换成字符串 lower 字符串转换成小写 num2str 数字转换成字符串 setstr ASCII 转换成字符串 sprintf 用格式控制,数字转换成字符串 sscanf 用格式控制,字符串转换成数字 str2mat 字符串转换成一个文本矩阵 str2num 字符串转换成数字 upper 字符串转换成大写 在许多情况下,希望把一个数值嵌入到字符串中。几个字符串转换可完成这个任务。 » rad=2.5; area=pi*rad^2; » t=[' A circle of radius ' num2str(rad) ' has an area of ' num2str(area) ' . ' ] ; » disp(t) A circle of radius 2.5 has an area of 19.63. 这里函数 num2str 用来把数值转换成字符串,字符串连接用来把所转换的数嵌人到一 个字符串句子中。按类似方式,int2str 把整数转换成字符串。无论是 num2str 还是 int2str 都调用函数 sprintf,它用类似 C 语言语法把数值转换成字符串。 函数 fprintf 经常是函数 disp 的一个有用替换,由于它提供了对结果更多的控制。当准 备把格式化的数据写到一个文件中去时,按缺省它在命令窗口显示结果。例如, » fprintf(' See what this does ') See what this does» » fprintf(' See what this does\n ') See what this does
在上面第一个例子里, fprintf显示字符串,然后立即给出 MATLAB提示符。相反,在 第二个例子里,Ⅶ插入一个新行字符,在 MATLAB提示符出现之前创建一个新行 无论 fprint还是 sprint以同样方式处理输入参量,但 fprintf把输出送到显示屏或文件 中,而 sprintf把输出返回到一个字符串中。例如,上面的例子用 num2str可重写为 >)tsprintf( A circle of radius %.4g has an area of %.4g. rad, area disp(t) A circle of radius 2.5 has an area of 19.63 >fprintf( A circle of radius %.4g has an area of %.4g. n, rad, area) A circle of radius 2.5 has an area of 19.63 这里%4g是用在函数mum2str中的数据格式。%轵就是用指数或定点标记,不管哪 种更短些,只显示至4位数字。除了g格式,还可用e(指数)和f(定点)转换。表62表明 在各种不同转换下,如何显示p结果。 表62 数值格式转换例子 命令 结果 fprintf('%.0eIn', pi 3e+00 fprintf(%.lein,pi) 3.le+00 fprintf(%.3eIn' pi 3.142e+00 fprintf( 3.14159e+00 fprintf('%.10eln', pi) 3.1415926536e+00 printf(%o.ofn’p) fprintf(%. 1f\n, pi) 3.1 fprintf(%.3f\n, pi) 3.142 fprintf(%.5f\n, pi) 3.14159 fprintf(%. 10f\n,pi 3.1415926536 fprintf(%.0gIn', pi) fprintf'%.1gIn', pi) fprintf(%.gin, pi) 3.14 fprintf'%.5gn, pi) 3.1416 fprintf(%.10gin, pi 3.141592654 fprintf(%.8.gin, pi fprintf(%.8.IgIn,pi) fprintf(%.8.3gIn,pi) 3.14 fprintf(%.8.5gin,pi) 3.1416 fprintf(%.8.10gin, pi) 3.141592654 注意,对e和f格式,小数点右边的十进制数就是小数点右边要显示的多少位数字
在上面第一个例子里,fprintf 显示字符串,然后立即给出 MATLAB 提示符。相反,在 第二个例子里,\n 插入一个新行字符,在 MATLAB 提示符出现之前创建一个新行。 无论 fprintf 还是 sprintf 以同样方式处理输入参量,但 fprintf 把输出送到显示屏或文件 中,而 sprintf 把输出返回到一个字符串中。例如,上面的例子用 num2str 可重写为 » t=sprintf(' A circle of radius %.4g has an area of %.4g. ', rad, area); » disp(t) A circle of radius 2.5 has an area of 19.63. » fprintf(' A circle of radius %.4g has an area of %.4g.\n ' , rad, area) A circle of radius 2.5 has an area of 19.63. 这里%.4g 是用在函数 num2str 中的数据格式。%.4g 就是用指数或定点标记,不管哪 一种更短些,只显示至 4 位数字。除了 g 格式,还可用 e (指数)和 f (定点)转换。表 6.2 表明 在各种不同转换下,如何显示 pi 结果。 表 6.2 数 值 格 式 转 换 例 子 命令 结果 fprintf(' %.0e\n ',pi) 3e+00 fprintf(' %.1e\n ',pi) 3.1e+00 fprintf(' %.3e\n ',pi) 3.142e+00 fprintf(' %.5e\n ',pi) 3.14159e+00 fprintf(' %.10e\n ',pi) 3.1415926536e+00 fprintf(' %.0f\n ',pi) 3 fprintf(' %.1f\n ',pi) 3.1 fprintf(' %.3f\n ',pi) 3.142 fprintf(' %.5f\n ',pi) 3.14159 fprintf(' %.10f\n ',pi) 3.1415926536 fprintf(' %.0g\n ',pi) 3 fprintf(' %.1g\n ',pi) 3 fprintf(' %.3g\n ',pi) 3.14 fprintf(' %.5g\n ',pi) 3.1416 fprintf(' %.10g\n ',pi) 3.141592654 fprintf(' %.8.0g\n ',pi) 3 fprintf(' %.8.1g\n ',pi) 3 fprintf(' %.8.3g\n ',pi) 3.14 fprintf(' %.8.5g\n ',pi) 3.1416 fprintf(' %.8.10g\n ',pi) 3.141592654 注意,对 e 和 f 格式,小数点右边的十进制数就是小数点右边要显示的多少位数字
相反,在g的格式里,小数点右边的十进制数指定了显示数字的总位数。另外,注意最后 的五行,其结果指定为8个字符长度,且是右对齐。在最后一行,8被忽略,因为指定超过 了8位 概括起来,当需要比缺省函数disp,num2str和int2str所提供的更多的控制 rIn 和 sprintf是有用的。 函数str2mat把一列的几个字符串转换成一个字符串矩阵。例如, >)a=' one. b='two. c=' three >)disp(str 2mat(a, b, c, ' four ) thre 尽管从上面看不明显,上面的每行有同样数目的元素。较短行用空格补齐,使结果形成 个有效的矩阵 在逆方向转换中,有时是很方便的 >)S='1 2; pi 4 a string of a MATLAB matrix [12,pi4] >>str2num(s 1.000020000 3.14164.0000 》s=123e a string containing a simple number 123e+5 >)str2num(s) 12300000 函数str2num不能接受用户定义的变量,也不能执行转换过程的算术运算。更多的信 息,请看在线帮助。 6.3字符串函数 MATLAB提供了大量的字符串函数,包括列在表6.3当中的
相反,在 g 的格式里,小数点右边的十进制数指定了显示数字的总位数。另外,注意最后 的五行,其结果指定为 8 个字符长度,且是右对齐。在最后一行,8 被忽略,因为指定超过 了 8 位。 概括起来,当需要比缺省函数 disp,num2str 和 int2str 所提供的更多的控制时,fprintf 和 sprintf 是有用的。 函数 str2mat 把一列的几个字符串转换成一个字符串矩阵。例如, » a=' one ' ; b= ' two ' ; c= ' three ' ; » disp(str2mat(a, b, c, ' four ')) one two three four 尽管从上面看不明显,上面的每行有同样数目的元素。较短行用空格补齐,使结果形成 一个有效的矩阵 在逆方向转换中,有时是很方便的。 » s= ' [1 2; pi 4] ' % a string of a MATLAB matrix s = [1 2; pi 4] » str2num(s) ans = 1.0000 2.0000 3.1416 4.0000 » s=' 123e+5 ' % a string containing a simple number s = 123e+5 » str2num(s) ans = 12300000 函数 str2num 不能接受用户定义的变量,也不能执行转换过程的算术运算。更多的信 息,请看在线帮助。 6.3 字符串函数 MATLAB 提供了大量的字符串函数,包括列在表 6.3 当中的
表6.3 字符串函数 eval(string) 作为一个 MATLAB命令求字符串的值 eval(try, catch) 返回一个n个零或空格的字符串 去掉字符串中后拖的空格 求由字符串给定的函数值 从一个字符串内找出字符串 字母存在时返回真值 空格字符存在时返回真值 输入是一个字符串,返回真值 返回上一个所产生 MATLAB错误的字符串 strcmp 字符串相同,返回真值 用一个字符串替换另一个字符串 strtok 在一个字符串里找出第一个标记 列在上面的第一个函数ea给 MATLAB提供宏的能力。其中,该函数提供了将用户创 建的函数名传给其它函数能力,以便求值。它的应用例子包括 》a=eval'sqrt(2)) 14142 eval( a=sqrt(2)) 14142 上面的例子演示了函数eval。显然,它们不是计算2的平方根的最简单方法。当被求值 的字符串是由子字符串连接而成,或将字符串传给一个函数以求值时,eval非常有用。说明 这种用途例子本书的以后会提及。 如果字符串传递到eval不能被辨认, MATLAB提供下列语法 >)eval( a=sqrt(2)a=[ ], 这里第二个参量被执行。由于第一个参量有误,即sqrt不是一个有效的 MATLAB函 数。这种形式经常被描述为eal(try, catch)。 函数 feval与eval类似,但在用法上有更多的限制。 feval(' fur;x)求由字符串fun'给 定的函数值,其输入参量是变量x。即 feral'fun',x)等价于求fun(x)值。例如
表 6.3 字 符 串 函 数 eval(string) 作为一个 MATLAB 命令求字符串的值 eval(try,catch) blanks(n) 返回一个 n 个零或空格的字符串 deblank 去掉字符串中后拖的空格 feval 求由字符串给定的函数值 findstr 从一个字符串内找出字符串 isletter 字母存在时返回真值 isspace 空格字符存在时返回真值 isstr 输入是一个字符串,返回真值 lasterr 返回上一个所产生 MATLAB 错误的字符串 strcmp 字符串相同,返回真值 strrep 用一个字符串替换另一个字符串 strtok 在一个字符串里找出第一个标记 列在上面的第一个函数 eval 给 MATLAB 提供宏的能力。其中,该函数提供了将用户创 建的函数名传给其它函数能力,以便求值。它的应用例子包括: » a=eval(' sqrt(2) ') a = 1.4142 » eval(' a=sqrt(2) ') a = 1.4142 上面的例子演示了函数 eval。显然,它们不是计算 2 的平方根的最简单方法。当被求值 的字符串是由子字符串连接而成,或将字符串传给一个函数以求值时,eval 非常有用。说明 这种用途例子本书的以后会提及。 如果字符串传递到 eval 不能被辨认,MATLAB 提供下列语法: » eval(' a=sqrtt(2) ',' a=[ ] ') a = [ ] 这里第二个参量被执行。由于第一个参量有误,即 sqrtt 不是一个有效的 MATLAB 函 数。这种形式经常被描述为 eval(try,catch)。 函数 feval 与 eval 类似,但在用法上有更多的限制。feval(' fun ',x)求由字符串' fun '给 定的函数值,其输入参量是变量 x。即 feval(' fun ',x)等价于求 fun(x)值。例如
>)a=feval( sqrt, 2) 函数eval, feval的基本用途限在用户创建的函数内。一般地, feval可求出有大量输入 参量的函数值,例如, feval(fun,x,y,z)等价于求fun(x,y,2)值 列在上面表中的许多字符串函数提供了基本的字符串语法分析能力。例如, findstr返 回一个在另一个字符串内字符串的起始下标值 >b= Peter Piper picked a peck of pickled peppers; >> findstr(b, find space ans 6121921262937 >)findstr(,p) find the letter p >find(b==p) for single character searches the find command works too 913 >findstr(b, 'cow) find the word cow >findstr(b, pick find the string pick ans 13 注意这个函数对大小写是敏感的,当不匹配时,返回空矩阵。 findstr对字符串矩阵不 起作用 >)strep(b, 'p,'P) o capitalize all p's Peter PiPer Picked a Peck of Pickled PePPers >)strep(b, 'Peter, 'Pamela) change Peter to Pamela ans Pamela Piper picked a peck of pickled peppers
» a=feval(' sqrt ' ,2) a = 1.4142 函数 eval,feval 的基本用途限在用户创建的函数内。一般地,feval 可求出有大量输入 参量的函数值,例如,feval(' fun ', x, y, z) 等价于求 fun(x, y, z)值。 列在上面表中的许多字符串函数提供了基本的字符串语法分析能力。例如,findstr 返 回一个在另一个字符串内字符串的起始下标值。 » b=' Peter Piper picked a peck of pickled peppers ' ; » findstr(b,' ') % find space ans = 6 12 19 21 26 29 37 » findstr(b,' p ') % find the letter p ans = 9 13 22 30 38 40 41 » find(b= = ' p ') % for single character searches the find command works too ans = 9 13 22 30 38 40 41 » findstr(b, ' cow ') % find the word cow ans = [ ] » findstr(b,' pick ') % find the string pick ans = 13 30 注意这个函数对大小写是敏感的,当不匹配时,返回空矩阵。findstr 对字符串矩阵不 起作用。 » strrep(b, ' p ', ' P ') % capitalize all p ' s ans = Peter PiPer Picked a Peck of Pickled PePPers » strrep(b, ' Peter ', ' Pamela ') % change Peter to Pamela ans = Pamela Piper picked a peck of pickled peppers
正如上面所看到的, strep执行简单的字符串替代。 strep对字符串矩阵不起作用。 函数 strtok找出由特定字符指定的字符串内的标记,空格是缺省限定字符。例如 >)disp(b) Peter Piper picked a peck of pickled peppers >)strtok(b) find first token in above string separated by whitespace >[c, r]=strtok(b) return the remainder of the string array inr Peter Piper picked a peck of pickled peppers >[d, s]=strtok(r)%find the next token by using the previous remainder Pi picked a peck of pickled peppers 用空格作为限定符, strtok找出在数组中的单词。 strtok对字符串矩阵不起作用。 >[d, s]=strtok(b, 'pP )%let delimiter be lower or upper case P d eter Piper picked a peck of pickled peppers 如果提供一个可选的字符串,它的字符是限定符。注意在标记里,不返回限定符,但返 回所有限定符之前的字符。也就是,在上面的字符串d=eter末端有一个空格
正如上面所看到的,strrep 执行简单的字符串替代。strrep 对字符串矩阵不起作用。 函数 strtok 找出由特定字符指定的字符串内的标记,空格是缺省限定字符。例如, » disp(b) Peter Piper picked a peck of pickled peppers » strtok(b) % find first token in above string separated by whitespace ans = Peter » [c, r]=strtok(b) % return the remainder of the string array in r c = Peter r = Piper picked a peck of pickled peppers » [d,s]=strtok(r) %find the next token by using the previous remainder d = Piper s = picked a peck of pickled peppers 用空格作为限定符,strtok 找出在数组中的单词。strtok 对字符串矩阵不起作用。 » [d, s]=strtok(b, ' pP ') %let delimiter be lower or upper case P d = eter s = Piper picked a peck of pickled peppers 如果提供一个可选的字符串,它的字符是限定符。注意在标记里,不返回限定符,但返 回所有限定符之前的字符。也就是,在上面的字符串 d = eter 末端有一个空格