正则表达式循环查找每个查询 TCL 的第一个实例
regexp loop to find first instance of each query TCL
我有一个包含一些值的列表变量:
lappend list {query1}
{query2}
{query3}
还有 file1 中的一些数据,其中部分数据与上述值匹配
query1 first data
query1 different data
query1 different data
query2 another data
query2 random data
query3 data something
query3 last data
如何创建一个正则表达式循环,它只捕获每个查询中找到的第一个实例并将它们打印出来?在这种情况下,输出将是:
query1 first data
query2 another data
query3 data something
尝试生成输出的代码
set readFile1 [open file1.txt r]
while { [gets $readFile1 data] > -1 } {
for { set n 0 } { $n < [llength $list] } { incr n } {
if { [regexp "[lindex $list $n]" $data] } {
puts $data
}
}
}
close $readFile1
我尝试在从文件中读取数据时使用 for 循环,但它似乎捕获了所有值,即使未使用 -all 选项也是如此。
如果文本文件较小,您可以使用 read
命令将文件作为一个整体读入变量。为内容应用 regexp
,我们可以提取所需的数据。
set list {query1 query2 query3}
set fp [open file1.txt r]
set data [read $fp]
close $fp
foreach elem $list {
# '-line' flag will enable the line sensitive matching
if {[regexp -line "$elem.+" $data line]} {
puts $line
}
}
如果假设文件太大而无法容纳,或者如果您考虑 运行-time 内存使用,则继续逐行阅读内容。在那里我们需要控制已经匹配的内容,您可以保留一个数组来维护任何查询的第一次匹配是否匹配。
set list {query1 query2 query3}
set fp [open file1.txt r]
array set first_occurence {}
while {[gets $fp line]!=-1} {
foreach elem $list {
if {[info exists first_occurence($elem)]} {
continue
}
if {[regexp $elem $line]} {
set first_occurence($elem) 1
puts $line
}
}
}
close $fp
参考:regexp
试试这个,
set fd [open "query_file.txt" r]
set data [read $fd]
set uniq_list ""
foreach l [split $data "\n"] {
lappend uniq_list [lindex $l 0]
}
set uniq_list [lsort -unique $uniq_list]
foreach l $uniq_list {
if {[string equal $l ""]} {
continue
}
foreach line [split $data "\n"] {
if {[regexp $l $line]} {
puts "$line"
break
}
}
}
close $fd
package require fileutil
set queries {query1 query2 query3}
set result {}
::fileutil::foreachLine line file1.txt {
foreach query $queries {
if {![dict exists $result $query]} {
if {[regexp $query $line]} {
dict set result $query $line
puts $line
}
}
}
}
这里的技巧是将发现存储在字典中。如果字典中已经有查询对应的值,我们就不再查找。这还有一个好处,即找到的行在搜索后可供脚本使用,而不仅仅是打印出来。 regexp
搜索查找行中任意位置的查询字符串:如果它只应在行的开头,请改用 regexp ^$query $line
。
文档:dict, fileutil package, foreach, if, package, puts, regexp, set
根本不使用正则表达式:我假设您的 "query" 不包含空格
set list [list query1 query2 query3]
array set seen {}
set fh [open file1]
while {[gets $fh line] != -1} {
set query [lindex [split $line] 0]
if {$query in $list && $query ni [array names seen]} {
set seen($query) 1
puts $line
}
}
query1 first data
query2 another data
query3 data something
我有一个包含一些值的列表变量:
lappend list {query1}
{query2}
{query3}
还有 file1 中的一些数据,其中部分数据与上述值匹配
query1 first data
query1 different data
query1 different data
query2 another data
query2 random data
query3 data something
query3 last data
如何创建一个正则表达式循环,它只捕获每个查询中找到的第一个实例并将它们打印出来?在这种情况下,输出将是:
query1 first data
query2 another data
query3 data something
尝试生成输出的代码
set readFile1 [open file1.txt r]
while { [gets $readFile1 data] > -1 } {
for { set n 0 } { $n < [llength $list] } { incr n } {
if { [regexp "[lindex $list $n]" $data] } {
puts $data
}
}
}
close $readFile1
我尝试在从文件中读取数据时使用 for 循环,但它似乎捕获了所有值,即使未使用 -all 选项也是如此。
如果文本文件较小,您可以使用 read
命令将文件作为一个整体读入变量。为内容应用 regexp
,我们可以提取所需的数据。
set list {query1 query2 query3}
set fp [open file1.txt r]
set data [read $fp]
close $fp
foreach elem $list {
# '-line' flag will enable the line sensitive matching
if {[regexp -line "$elem.+" $data line]} {
puts $line
}
}
如果假设文件太大而无法容纳,或者如果您考虑 运行-time 内存使用,则继续逐行阅读内容。在那里我们需要控制已经匹配的内容,您可以保留一个数组来维护任何查询的第一次匹配是否匹配。
set list {query1 query2 query3}
set fp [open file1.txt r]
array set first_occurence {}
while {[gets $fp line]!=-1} {
foreach elem $list {
if {[info exists first_occurence($elem)]} {
continue
}
if {[regexp $elem $line]} {
set first_occurence($elem) 1
puts $line
}
}
}
close $fp
参考:regexp
试试这个,
set fd [open "query_file.txt" r]
set data [read $fd]
set uniq_list ""
foreach l [split $data "\n"] {
lappend uniq_list [lindex $l 0]
}
set uniq_list [lsort -unique $uniq_list]
foreach l $uniq_list {
if {[string equal $l ""]} {
continue
}
foreach line [split $data "\n"] {
if {[regexp $l $line]} {
puts "$line"
break
}
}
}
close $fd
package require fileutil
set queries {query1 query2 query3}
set result {}
::fileutil::foreachLine line file1.txt {
foreach query $queries {
if {![dict exists $result $query]} {
if {[regexp $query $line]} {
dict set result $query $line
puts $line
}
}
}
}
这里的技巧是将发现存储在字典中。如果字典中已经有查询对应的值,我们就不再查找。这还有一个好处,即找到的行在搜索后可供脚本使用,而不仅仅是打印出来。 regexp
搜索查找行中任意位置的查询字符串:如果它只应在行的开头,请改用 regexp ^$query $line
。
文档:dict, fileutil package, foreach, if, package, puts, regexp, set
根本不使用正则表达式:我假设您的 "query" 不包含空格
set list [list query1 query2 query3]
array set seen {}
set fh [open file1]
while {[gets $fh line] != -1} {
set query [lindex [split $line] 0]
if {$query in $list && $query ni [array names seen]} {
set seen($query) 1
puts $line
}
}
query1 first data
query2 another data
query3 data something