找到删除行正则表达式

时间:2014-06-27 18:45:41

标签: regex tcl

我希望迭代一个文件,找到某些模式,如果找到那个模式,删除它所在的整行。

这是我目前所拥有的:

#  Slurp up the data files
set fp [open "params.txt" r]
set file_data [read $fp]
close $fp

set fp [open [lindex $argv 0] r ]
set configFile [read $fp] 
close $fp

#  Process data file
set data [split $file_data "\n"]
    foreach line $data {

    # do some line processing here
    if { "$data" != "" } { 

        if { [ regexp {\b"$data"\b} $configFile ] == 1 } {
            #Remove entire line regex is found on in $configFile
        }
    }
}
#write $configFile to a file

该脚本将只有一个参数,即“haystack”,params.txt是一个硬编码的“针”列表。我的问题是正则表达式返回true或false,所以我不知道如何到达正确的行,然后删除整个行。

让它变得更加棘手的是params.txt中的大多数项目都是“我不想删除的内容”(例如下面的内容)

apple starts with "a"
applepie is delicious
pineapple is delicious

我想删除行apple starts with "a",但不要触及其他行。我说“单词”,因为我还有get parameters之类的东西作为我要查找和删除的“单词”。

3 个答案:

答案 0 :(得分:2)

如果我们假设params.txt中的单词只是字母(+可能是数字和下划线,即不是RE metasyntax),每行一个,那么我们可以这样做:

# Read in config
set fp [open "params.txt"]
set words [split [read $fp] "\n"]
close $fp

# Read in data
set fp [open "inputData.txt"]
set lines [read $fp]
close $fp

# Process it all
foreach word $words {
    regsub -all -line "^.*\\y$word\\y.*(?:\n|$)" $lines "" lines
}

# Write out
set fp [open "outputData.txt" w]
puts -nonewline $fp $lines
close $fp

真正的关键是:

regsub -all -line "^.*\\y$word\\y.*(?:\n|$)" $lines "" lines

有趣的是:

  • -line,它将regsub置于行匹配模式而不是默认的“整个字符串匹配”模式(影响^.和{{1}的方式工作),
  • $,它使-all替换所有可能的匹配,而不仅仅是第一个匹配,
  • regsub,它是RE引擎的\\y,与字边界匹配,
  • \y匹配末尾的换行符字符串/行的末尾,因此该行被删除而不仅仅是清除。

如果配置中的每一行都比这更常规,那么在(?:\n|$)中使用它之前,你需要做一些额外的工作才能使它“好”。幸运的是,regsub是适合它的工具!

regsub

答案 1 :(得分:1)

我认为你需要这样的东西,

.*\bapple\b.*

它将匹配包含确切单词apple的行。只需删除匹配的行即可获得所需的结果。

DEMO

答案 2 :(得分:0)

我会这样做:

#  Slurp up the data files
set fp [open "params.txt" r]
set fileData [split [read -nonewline $fp] \n]
close $fp

set fp [open [lindex $argv 0] r ]
set configData [split [read -nonewline $fp] \n]
close $fp

#  Process data file
foreach line $fileData {
    set configData [lsearch -not -all -inline -regexp "\\m$line\\M" $configData]
}

使用-nonewline,这样你就不会得到错误的"拆分后的空行。
我更喜欢\m\M明确单词的开头和结尾 由于你需要替换变量,正则表达式需要用双引号,你需要加倍反斜杠。

http://tcl.tk/man/tcl8.5/TclCmd/lsearch.htm
http://tcl.tk/man/tcl8.5/TclCmd/re_syntax.htm#M72

相关问题