[unix_tcl]tcl命令 regexp regsub
(2011-12-21 17:57:56)
标签:
tcl命令it |
分类: unix/linux |
语法: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 正好子串“ 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〕了,即使后面有以'-'开头的参数也被当作正规表达式的一部分。 |
语法: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]"