在tcl中捕获文件中的多个空行
我的文件中有4个空格,设置在wr_fp中。我想在代码中捕获4个空格。但下面的代码不起作用在tcl中捕获文件中的多个空行,tcl,Tcl,我的文件中有4个空格,设置在wr_fp中。我想在代码中捕获4个空格。但下面的代码不起作用 while {[gets $wr_fp line3] >= 0} { if {[regexp "\n\s+\n\s+\n\s+\n" $line3]} { puts "found 4 empty lines"} } tl;dr:不要把REs放在“引号”,把它们放在{大括号}中 问题是你把你的RE加了引号,所以它实际上是这样的: + + + 由于Tcl的原因,\n变成了一个新行,\s变成了一个简单的s
while {[gets $wr_fp line3] >= 0} {
if {[regexp "\n\s+\n\s+\n\s+\n" $line3]} { puts "found 4 empty lines"}
}
tl;dr:不要把REs放在
“
引号”
,把它们放在{
大括号}
中
问题是你把你的RE加了引号,所以它实际上是这样的:
+
+
+
由于Tcl的原因,
\n
变成了一个新行,\s
变成了一个简单的s
。将RE放在大括号中会抑制这种(在本例中不需要的)行为。使用get
/chan-get
命令一次读取一行,并丢弃每行的换行符,因此测试将永远不会成功。您需要立即读入文件的全部内容:
set txt [chan read $wr_fp]
if {[regexp {\n\s+\n\s+\n\s+\n} $txt]} { puts "found 4 empty lines"}
注意,正如Donal所解释的,您需要在正则表达式周围使用大括号
关于重新表述的一些典型陷阱:
- 是否确实要指定每个“空”行上必须至少有一个空白字符?如果要允许换行符之间的行完全没有字符,请使用
而不是\s*
\s+
- 还请注意,此正则表达式将匹配具有四个以上换行符的范围:额外的换行符将由一个
组使用。如果要禁止使用额外的换行符,请使用(例如)\s+
(或您想要的任何其他空白组合)而不是[\t\f\r]
。请注意,这意味着表达式将恰好匹配三行,其中只有空格、制表符、换行符和返回,这些行由换行符包围和分隔:您可能希望用一个子组将其扩展以匹配第四行\s
abc
def
ghi
jkl
mno
pqr
stu
vwx
yz.
(如果“pqr”后的第二行中有制表符)
<代码>假设代码>计数<代码>代码被调用时的值0,您的代码在“DEF”、“PQR”和“VWX”读取空白行之后输出“找到4个空间”,而不是在“STU”之前的行之后,您的问题指出它应该是.
此代码
set count 0
while {[gets $rd_fp line] >= 0} {
if {[string is space $line]} {
incr count
if {$count == 4} {puts "found 4 space"}
} else {
set count 0
}
}
是否按您的要求执行(几乎):它接受包含空格的行为空,并且仅在找到四个连续的空行后才打印其消息。与您问题中的规范的主要区别在于,它还接受没有任何字符的行为空。为了符合您的规范,字符串是空格-应该使用严格的$line
文档:,,,这是我的答案。我想要这个
while {[gets $rd_fp line] >= 0} {
if {[string match "" $line]} {
if {[expr $count % 4] == 1} {puts "found 4 space"}
incr count
}
}
您正在逐行读取文件并在同一行上检查“换行符和空格”?您最好将所有内容作为一个整体读取到一个变量中,然后应用此
regexp
。如果您逐行读取,则将其附加到一个变量,然后应用regexp
。在某些情况下,在引号中加上RE是有意义的,例如,当您使用的是由较小的子分辨率重新构建的RE时。尽管这是非常高级的用法;你通常不想做那种事。在RE周围加括号可以防止各种潜在的复杂性…
while {[gets $rd_fp line] >= 0} {
if {[string match "" $line]} {
if {[expr $count % 4] == 1} {puts "found 4 space"}
incr count
}
}