Perl搜索替换为负向前瞻

时间:2014-05-20 03:05:05

标签: regex perl bash

这个让我发疯。尝试使用perl进行命令行搜索/替换。基本上我想要删除所有不在XLS(X)中结束的文件路径,但它们必须以字符串NATIVE开头。提前谢谢!

命令

cat test.txt | perl -ne 's/"(?!NATIVE[^"]+XLSX?)"/""/g; print;'

的test.txt

"Blah","NATIVE/001/FOO.XLS","Blah"
"Blah","NATIVE/001/BAR.XLSX","Blah"
"Blah","NATIVE/001/FOO.DOC","Blah"
"Blah","NATIVE/001/FOO.PPT","Blah"
"Blah","NATIVE/001/FOO.PPTX","Blah"
"Blah","NATIVE/001/FOO.PNG","Blah"

预期产出

"Blah","NATIVE/001/FOO.XLS","Blah"
"Blah","NATIVE/001/BAR.XLSX","Blah"
"Blah","","Blah"
"Blah","","Blah"
"Blah","","Blah"
"Blah","","Blah"

实际输出

"Blah","NATIVE/001/FOO.XLS","Blah"
"Blah","NATIVE/001/BAR.XLSX","Blah"
"Blah","NATIVE/001/FOO.DOC","Blah"
"Blah","NATIVE/001/FOO.PPT","Blah"
"Blah","NATIVE/001/FOO.PPTX","Blah"
"Blah","NATIVE/001/FOO.PNG","Blah"

5 个答案:

答案 0 :(得分:1)

您可以使用lookbehinds尝试此模式:

cat test.txt | perl -ne 's/"NATIVE\/[^"]+(?<!\.XLS)(?<!\.XLSX)"/""/g; print;'

cat test.txt | perl -ne 's/"NATIVE\/[^"]++(?<!\.XLS)(?<!\.XLSX)/"/g; print;'

你需要确保lookbehinds在结束报价之前开始。要做到这一点,你有两种方法:写出结束语或使用占有量词。

答案 1 :(得分:1)

使用perl one-liner

perl -pe 's/"NATIVE[^"]+(?<!\.XLSX)(?<!\.XLS)"/""/g;' test.txt

基本上,使用负面的lookbehind断言。而且因为它们不能长度可变,所以只需使用两个。

注意,如果有时断言太具有挑战性,您可以使用/ e修饰符分解逻辑。以下也可以工作,只需两步有条件地进行更换:

perl -pe 's/"\K(NATIVE[^"]+)/$1 =~ m{XLSX?$} ? $1 : ""/eg;' test.txt

答案 2 :(得分:1)

您想在此处使用负面反对

cat test.txt | perl -ne 's/"NATIVE[^"]+(?<!\.XLS|XLSX)"/""/g; print;'

您也可以使用Lookahead和Lookbehind作为报价。

cat test.txt | perl -ne 's/(?<=")NATIVE[^"]+(?<!\.XLS|XLSX)(?=")//g; print;'

输出

"Blah","NATIVE/001/FOO.XLS","Blah"
"Blah","NATIVE/001/BAR.XLSX","Blah"
"Blah","","Blah"
"Blah","","Blah"
"Blah","","Blah"
"Blah","","Blah"

答案 3 :(得分:0)

这是我的尝试模式(?<=")NATIVE[^.]*\.(?!\XLSX?")[^"]+
Demo

答案 4 :(得分:0)

无需外观:

cat test.txt | perl -ne 's/"NATIVE(?![^"]+XLSX?")[^"]*"/""/g; print;'