【问题标题】:How to match a string unless it contains something?除非它包含某些内容,否则如何匹配字符串?
【发布时间】:2015-05-27 14:57:30
【问题描述】:

我有一个 PowerShell 脚本,它将获取文件夹中所有文件的列表,然后(基于 Switch 语句中的正则表达式匹配)将每个文件移动到指定文件夹(取决于正则表达式匹配)。

我对特定列表有疑问。以“40”开头的一组文件(以其部件号命名的 PDF 文件)被移动到指定文件夹。

正则表达式本身对我来说很容易,我遇到的问题是,如果文件包含 _ol_ol_,那么它不能匹配。

例如,下面的文件名应该都匹配:

401234567.pdf
401234567a.pdf
401234567_a.pdf
401234567a_something.pdf

以下内容不应匹配:

401234567_ol.pdf
401234567_ol_something.pdf

使用^(?i)40\w+[^_ol].pdf$ 正则表达式似乎是我能得到的最接近的。 它将否定401234567_ol.pdf 作为匹配项;但是,它接受401234567_ol_something.pdf。有谁知道我怎么能否定它是匹配的?

【问题讨论】:

    标签: regex powershell


    【解决方案1】:

    您可以在您的正则表达式中使用否定的前瞻性。以下正则表达式将匹配任何不包含 _ol 的字符串:

    ^((?!_ol).)*$
    

    DEMO

    注意,多行字符串需要使用修饰符m(多行)。

    【讨论】:

      【解决方案2】:

      使用否定的前瞻:

      ^(?i)(?!.*_ol)40\w+\.pdf$
      

      demo

      模式开头的前瞻(?!.*_ol) 检查字符串后面是否没有_ol。如果存在,我们没有匹配项。点必须转义以匹配文字点。

      【讨论】:

      • 谢谢,知道很快就会有答复。我确实尝试过(消极的前瞻性想法);但是,语法不正确。
      • 您能否也发布该尝试以便我对此发表评论?
      • 另外,如果它对您有用,请考虑接受答案。
      【解决方案3】:

      只需将-notmatch operator 与您要排除的模式匹配:

      Get-ChildItem 'C:\source' -Filter '*.pdf' |
        ? { $_.BaseName -notmatch '_ol(_|$)' } |
        Move-Item -Destination 'C:\destination'
      

      -notlike 运算符(以获得更好的性能):

      Get-ChildItem 'C:\source' -Filter '*.pdf' |
        ? { $_.BaseName -notlike '*_ol' -and $_.BaseName -notlike '*_ol_*' } |
        Move-Item -Destination 'C:\destination'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-03-24
        • 1970-01-01
        • 2015-03-07
        • 1970-01-01
        • 2010-12-19
        • 1970-01-01
        • 2011-03-31
        相关资源
        最近更新 更多