如何确保我的正则表达式不匹配太多

时间:2011-08-18 10:09:50

标签: tcl

一个文件在它们的开头几乎没有数字。我想提取一个特定的无行。当给出1时,它也用11,21

提取第1行

FILE.txt有内容:

1.sample
lines of
2.sentences
present in
...
...
10.the 
11.file

执行pro 1 file.txt时 给出了第1,10行和第11行的结果 因为这三个结果在他们的字符串中有1个。即

脚本输出:

1.sample
10.the 
11.file

预期产出:我期待的产出 仅是第1行内容而不是第10行或第11行内容。 即

预期产出:

1.sample

我目前的代码:

proc pro { pattern args} {

   set file [open $args r]
   set lnum 0
   set occ 0 
   while {[gets $file line] >=0} {
      incr lnum
      if {[regexp $pattern $line]} {
          incr occ
          puts "The pattern is present in line: $lnum" 
          puts "$line"
      } else {
         puts "not found"
      }
   }
   puts "total number of occurencese : $occ"
   close $file
}

该程序工作正常,但问题是我正在检索我不想要的行以及预期的行。由于我想要检索的数字(1)存在于其他字符串中,例如11,21,14等,这些行也会被打印出来。

请理解我不清楚的解释问题的方法。

3 个答案:

答案 0 :(得分:1)

您可以使用glen建议的单词边界来解决问题,但您也可以考虑以下事项:

如果在每个行号之后都有.,那么您可以将它用作正则表达式中的分隔符

regexp "^$lineNo\\." $a

我还建议使用^(在行的开头匹配),这样即使其他地方的行中存在数字,也不会计算。

单词边界在http://www.regular-expressions.info/wordboundaries.html

处得到了很好的解释

答案 1 :(得分:0)

您必须确保您的模式仅在单词边界之间匹配:

if {[regexp "\\m$pattern\\M" $line]} { ...

请参阅regular expression syntax的文档。

答案 2 :(得分:0)

如果您要做的事情与您所描述的内容一样受限制,为什么不使用像

这样的内容?
if { [string range $line 0 [string length $pattern]] eq "${pattern}." } {
    ...
}