【问题标题】:Perl search replace with negative lookaheadPerl 搜索替换为负前瞻
【发布时间】:2014-05-20 13:06:58
【问题描述】:

这个让我发疯。尝试使用 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"

【问题讨论】:

    标签: regex perl bash


    【解决方案1】:

    您可以通过lookbehinds尝试这种模式:

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

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

    您需要确保在结束引号之前开始回溯。为此,您有两种方法:写结束引号或使用所有格量词。

    【讨论】:

    • 就是这样!看起来 [^"]+ 捕获了字段末尾的所有内容,因此我的 lookAHEAD 不匹配。谢谢!!
    【解决方案2】:

    您想在此处使用 Negative Lookbehind

    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】:

      使用 perl 单行代码

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

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

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

          无需往后看:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2013-11-09
            • 1970-01-01
            • 1970-01-01
            • 2010-11-05
            • 1970-01-01
            • 2019-05-05
            • 1970-01-01
            相关资源
            最近更新 更多