Regex TCL中的负正则表达式
我有一个变量Regex TCL中的负正则表达式,regex,tcl,Regex,Tcl,我有一个变量text,它是一个包含或不包含“u backup”的文件名。我需要一个正则表达式,它可以选择一个文件名,其中没有“\u backup”(如果它有*\u backup.txt,则排除)。我想在TCL中实现这一点(而不是Ruby。我使用Ruby进行说明)。我有下面这样的正则表达式 text = "some_thing.txt" text =~ /\S+[^_backup]\.txt/ # => 0 #-> correct as filename does not have _
text
,它是一个包含或不包含“u backup”
的文件名。我需要一个正则表达式,它可以选择一个文件名,其中没有“\u backup”
(如果它有*\u backup.txt
,则排除)。我想在TCL中实现这一点(而不是Ruby。我使用Ruby进行说明)。我有下面这样的正则表达式
text = "some_thing.txt"
text =~ /\S+[^_backup]\.txt/
# => 0 #-> correct as filename does not have _backup
text = "some_thinp.txt"
text =~ /\S+[^_backup]\.txt/
# => nil #-> Wrong, filename does not have _backup (returns nil as last character before .txt 'p' is one among the characters given in exclude list.
上述代码的问题是,排除按字符(任何字符)进行,并以文件名失败,该文件名以
'p'
字符结尾,该字符在'.txt'
之前的排除列表中给出。如何构造排除word一部分的正则表达式?有许多聪明的方法来表示“负匹配”,但最简单、最可读的方法是从外部否定直接匹配:
if {![regexp {_backup} $text]} {
# do something with a name that does not contain '_backup'
set filename [file tail $text]
}
(我假设标准操作是获取$text
中给定路径的文件名和扩展名部分)或
随着正则表达式变得越来越复杂,代码通常变得越来越难理解。如果可以通过直接匹配和If
命令来完成任务,那么这总比神秘的正则表达式好
可以使用字符串匹配来代替regexp
:
if {![string match {*_backup*} $text]} {
# do something with a name that does not contain '_backup'
set filename [file tail $text]
}
如果变量text
中有文件路径字符串列表,则应该能够过滤掉不包含字符串\u backup
的字符串,如下所示:
set filenames [lmap text $texts {
expr {
[regexp {_backup} $text]
? [continue]
: [file tail $text]
}
}]
或者,相当于:
set filenames [lmap text $texts {
if {[regexp {_backup} $text]} continue
file tail $text
}]
set filenames {}
foreach text $texts {
if {[regexp {_backup} $text]} continue
lappend filenames [file tail $text]
}
或者,仍然相当于:
set filenames [lmap text $texts {
if {[regexp {_backup} $text]} continue
file tail $text
}]
set filenames {}
foreach text $texts {
if {[regexp {_backup} $text]} continue
lappend filenames [file tail $text]
}
文档链接:
Tcl 8.6引入了lmap
命令。可以找到与Tcl 8.4和Tcl 8.5兼容的纯Tcl实现
(好吧,耶!对这个答案的回答使我的声誉达到了.Thx!)你想排除带有\u backup
的文件名,还是带有\u backup.txt
的文件名?哪个?“排除word的一部分”是什么意思?@sawa:filenames with\u backup