加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

[unix_tcl]tcl命令 regexp regsub

(2011-12-21 17:57:56)
标签:

tcl

命令

it

分类: unix/linux
TCL- regexp命令

语法:regexp ?switchs? ?--? exp string ?matchVar?\ ?subMatchVar subMatchVar...?
regexp命令用于判断正规表达式exp是否全部或部分匹配字符串string,匹配返回1,否则0。

在正规表达式中,一些字符具有特殊的含义,下表一一列出,并给予了解释。
 

字符 意义
. 匹配任意单个字符
^ 表示从头进行匹配
$ 表示从末尾进行匹配
\x 匹配字符x,这可以抑制字符x的含义
[chars] 匹配字符集合chars中给出的任意字符,如果chars中的第一个字符是^,表示匹配任意不在chars中的字符,chars的表示方法支持a-z之类的表示。
(regexp) 把regexp作为一个单项进行匹配
* 对*前面的项0进行次或多次匹配
+ 对+前面的项进行1次或多次匹配
? 对?前面的项进行0次或1次匹配
regexp1|regexp2 匹配regexp1或regexp2中的一项

 

下面的一个例子是从《Tcl and Tk ToolKit》中摘下来的,下面进行说明:

^((0x)?[0-9a-fA-F]+|[0-9]+)$

这个正规表达式匹配任何十六进制或十进制的整数。

两个正规表达式以|分开(0x)?[0-9a-fA-F]+和[0-9]+,表示可以匹配其中的任何一个,事实上前者匹配十六进制,后者匹配的十进制。

^表示必须从头进行匹配,从而上述正规表达式不匹配jk12之类不是以0x或数字开头的串。

$表示必须从末尾开始匹配,从而上述正规表达式不匹配12jk之类不是数字或a-fA-F结尾的串。

下面以(0x)?[0-9a-fA-F]+ 进行说明,(0x)表示0x一起作为一项,?表示前一项(0x)可以出现0次或多次,[0-9a-fA-F]表示可以是任意0到9之间的单个数字或a到f或A到F之间的单个字母,+表示象前面那样的单个数字或字母可以重复出现一次或多次。

% regexp {^((0x)?[0-9a-fA-F]+|[0-9]+)$} ab
1
% regexp {^((0x)?[0-9a-fA-F]+|[0-9]+)$} 0xabcd
1
% regexp {^((0x)?[0-9a-fA-F]+|[0-9]+)$} 12345
1
% regexp {^((0x)?[0-9a-fA-F]+|[0-9]+)$} 123j
0

如果regexp命令后面有参数matchVar和subMatchVar,则所有的参数被当作变量名,如果变量不存在,就会被生成。 regexp把匹配整个正规表达式的子字符串赋给第一个变量,匹配正规表达式的最左边的子表达式的子字符串赋给第二个变量,依次类推,例如:

% regexp { ([0-9]+) *([a-z]+)} " there is 100 apples" total num word
1
% puts " $total ,$num,$word"
100 apples ,100,apples

regexp可以设置一些开关(switchs〕,来控制匹配结果:

开关 意义
-nocase 匹配时不考虑大小写
-indices 改变各个变量的值,这使各个变量的值变成了对应的匹配子串在整个字符串中所处位置的索引。例如:

% regexp -indices { ([0-9]+) *([a-z]+)} " there is 100 apples" total num word
1
% puts " $total ,$num,$word"
9 20 ,10 12,15 20

正好子串“ 100 apples”的序号是9-20,"100"的序号是10-12,"apples"的序号是15-20

-about 返回正则表达式本身的信息,而不是对缓冲区的解析。返回的是一个list,第一个元素是子表达式的个数,第二个元素开始存放子表达式的信息
-expanded 启用扩展的规则,将空格和注释忽略掉,相当于使用内嵌语法(?x)
-line 启用行敏感匹配。正常情况下^$只能匹配缓冲区起始和末尾,对于缓冲区内部新的行是不能匹配的,通过这个开关可以使缓冲区内部新的行也可以被匹配。它相当于同时使用-linestop和-lineanchor
开关,或者使用内嵌语法
(?n)
-linestop 启动行结束敏感开关。使^可以匹配缓冲区内部的新行。相当于内嵌语法(?p)
-lineanchor 改变^$的匹配行为,使可以匹配缓冲区内部的新行。相当于内嵌语法(?w)
-all 进最大可能的匹配
-inline Causes the command to return, as a list, the data that would otherwise be placed in match variables. When using -inline, match variables may not be specified. If used with -all, the list will be concatenated at each iteration, such that a flat list is always returned. For each match iteration, the command will append the overall match data, plus one element for each subexpression in the regular expression. Examples are:

regexp -inline -- {\w(\w)} " inlined "
=> {in n}
regexp -all -inline -- {\w(\w)} " inlined "
=> {in n li i ne e}
-start index 强制从偏移为index开始的位置进行匹配。使用这个开关之后,^将不能匹配行起始位置,\A将匹配字符串的index偏移位置。如果使用了-indices开关,则indices表示绝对位置,index表示输入字符的相对位置。
-- 表示这后面再没有开关(switchs〕了,即使后面有以'-'开头的参数也被当作正规表达式的一部分。

 

 

 

TCL-regsub命令

语法:regsub ?switchs? exp string subSpec varname
regsub的第一个参数是一个整个表达式,第二个参数是一个输入字符串,这一点和regexp命令完全一样,也是当匹配时返回1,否则返回0。不过regsub用第三个参数的值来替换字符串string中和正规表达式匹配的部分,第四个参数被认为是一个变量,替换后的字符串存入这个变量中。例如:

% regsub there "They live there lives " their x
1
% puts $x
They live their lives

这里there被用their替换了。

regsub命令也有几个开关(switchs):

-nocase 意义同regexp命令中。

-all 没有这个开关时,regsub只替换第一个匹配,有了这个开关,regsub将把所有匹配的地方全部替换。

-- 意义同regexp命令中。

 

 

 

帮助文档上的例子

set sample "Where there is a will, There is a way."

set result [regexp {[a-z]+} $sample match]
puts "Result: $result match: $match"

set result [regexp {([A-Za-z]+) +([a-z]+)} $sample match sub1 sub2 ]
puts "Result: $result Match: $match 1: $sub1 2: $sub2"

# 输出 :Result: 1 Match:where There 1:Where 2:There

regsub "way" $sample "lawsuit" sample2
puts "New: $sample2"

puts "Number of words: [regexp -all {[^ ]} $sample]"

 

 

 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有