Regex 需要一个正则表达式,其中一个字符串中不能包含两个不同的子字符串

Regex 需要一个正则表达式,其中一个字符串中不能包含两个不同的子字符串,regex,powershell,Regex,Powershell,我有以下字符串: $string = @( 'Get-WindowsDevel' 'Put-WindowsDevel' 'Get-LinuxDevel' 'Put-LinuxDevel' ) 现在我需要一个带有以下两条规则的正则表达式: $string不能以“Get…”开头 $string不能包含“Linux” 这排除了开头的“Get-”: PS C:\> $string | Where-Object { $_ -match "^(?!Get-).*" } 放置Wind

我有以下字符串:

$string = @(
  'Get-WindowsDevel'
  'Put-WindowsDevel'
  'Get-LinuxDevel'
  'Put-LinuxDevel'
)
现在我需要一个带有以下两条规则的正则表达式:

  • $string
    不能以“Get…”开头
  • $string
    不能包含“Linux”
  • 这排除了开头的“Get-”:

    PS C:\> $string | Where-Object { $_ -match "^(?!Get-).*" }
    
    放置WindowsDevel
    放置LinuxDevel

    我希望以下命令与“Put LinuxDevel”不匹配,但它确实匹配:

    PS C:\> $string | Where-Object { $_ -match "^(?!Get-).*(?!Linux)" }
    
    放置WindowsDevel
    放置LinuxDevel

    所以,我需要的是一个只对这个字符串有效的正则表达式:

    把窗户打开


    这似乎是你想要的[咧嘴笑]

    输出

    Put-WindowsDevel
    

    这似乎是你想要的[咧嘴笑]

    输出

    Put-WindowsDevel
    

    使用
    -notmatch
    (或者,如果需要区分大小写的匹配,
    -cnotmatch
    )-即一个否定匹配-与交替(
    )结合使用:

    • -match
      操作符及其变体(以及许多其他操作符)可以作为LHS直接作用于数组,在这种情况下,操作符充当过滤器并仅返回匹配元素

      • 在数组上使用
        -match
        比在管道中使用
        Where-Object
        cmdlet进行筛选快得多
    • Regex
      (^Get-| Linux)
      匹配字符串开头(
      ^
      )或(
      )子字符串
      Linux
      中的任意位置。
      因此,这个正则表达式匹配您不想要的字符串,并且通过使用否定形式
      -match
      -
      -notmatch
      -您可以根据需要排除这些字符串


    如果您真的想将正则表达式表示为正匹配

    PS> $string -match '^(?!Get)((?!Linux).)*$'
    Put-WindowsDevel
    
    PS> '', 'inux', 'Linux', 'a Linux', 'aLinuxb' -match '^((?!Linux).)*$'
                      # '' (empty string) matched
    inux              # 'inux' matched
    
    然而,请注意,这个正则表达式不仅要复杂得多,而且性能也会更差(尽管只是稍微差一点)


    至于你所尝试的:

    PS> $string -match '^(?!Get)((?!Linux).)*$'
    Put-WindowsDevel
    
    PS> '', 'inux', 'Linux', 'a Linux', 'aLinuxb' -match '^((?!Linux).)*$'
                      # '' (empty string) matched
    inux              # 'inux' matched
    
    正则表达式的
    *(?!Linux)
    部分(涉及a)在排除包含子字符串
    Linux
    的字符串时无效;e、 g:

    PS> 'Linux' -match '.*(?!Linux)'
    True # !!
    
    原因是
    *
    匹配整个字符串,然后向前看是否不存在
    Linux
    ——字符串末尾显然是这样

    为了有效地排除子字符串,必须在整个字符串的每个字符周围应用断言

    PS> $string -match '^(?!Get)((?!Linux).)*$'
    Put-WindowsDevel
    
    PS> '', 'inux', 'Linux', 'a Linux', 'aLinuxb' -match '^((?!Linux).)*$'
                      # '' (empty string) matched
    inux              # 'inux' matched
    

    请注意如何正确排除
    'Linux'
    'a Linux'
    'aLinuxb'

    使用
    -notmatch
    (或者,如果需要区分大小写的匹配,
    -cnotmatch
    )-即否定匹配-与替换(
    ):

    • -match
      操作符及其变体(以及许多其他操作符)可以作为LHS直接作用于数组,在这种情况下,操作符充当过滤器并仅返回匹配元素

      • 在数组上使用
        -match
        比在管道中使用
        Where-Object
        cmdlet进行筛选快得多
    • Regex
      (^Get-| Linux)
      匹配字符串开头(
      ^
      )或(
      )子字符串
      Linux
      中的任意位置。
      因此,这个正则表达式匹配您不想要的字符串,并且通过使用否定形式
      -match
      -
      -notmatch
      -您可以根据需要排除这些字符串


    如果您真的想将正则表达式表示为正匹配

    PS> $string -match '^(?!Get)((?!Linux).)*$'
    Put-WindowsDevel
    
    PS> '', 'inux', 'Linux', 'a Linux', 'aLinuxb' -match '^((?!Linux).)*$'
                      # '' (empty string) matched
    inux              # 'inux' matched
    
    然而,请注意,这个正则表达式不仅要复杂得多,而且性能也会更差(尽管只是稍微差一点)


    至于你所尝试的:

    PS> $string -match '^(?!Get)((?!Linux).)*$'
    Put-WindowsDevel
    
    PS> '', 'inux', 'Linux', 'a Linux', 'aLinuxb' -match '^((?!Linux).)*$'
                      # '' (empty string) matched
    inux              # 'inux' matched
    
    正则表达式的
    *(?!Linux)
    部分(涉及a)在排除包含子字符串
    Linux
    的字符串时无效;e、 g:

    PS> 'Linux' -match '.*(?!Linux)'
    True # !!
    
    原因是
    *
    匹配整个字符串,然后向前看是否不存在
    Linux
    ——字符串末尾显然是这样

    为了有效地排除子字符串,必须在整个字符串的每个字符周围应用断言

    PS> $string -match '^(?!Get)((?!Linux).)*$'
    Put-WindowsDevel
    
    PS> '', 'inux', 'Linux', 'a Linux', 'aLinuxb' -match '^((?!Linux).)*$'
                      # '' (empty string) matched
    inux              # 'inux' matched
    

    请注意如何正确排除
    'Linux'
    'a Linux'
    'aLinuxb'

    谢谢。你是对的,这会起作用,但是有没有办法将正则表达式字符串定义为一个与“-match”(而不是“-notmatch”)一起工作的字符串?原因是我从配置文件(json)中读取了该正则表达式字符串以及许多其他正则表达式字符串,并且不是所有的正则表达式字符串都是“notmatches”“@MichaelHellmann-如果您在豪华环境中进行此操作,您可以根据需要链接任意多个
    -match
    &
    -notmatch
    操作。[grin]为了安全起见,当我这样做时,我通常会转义字符串,比如:
    $regexcludelist=($ExcludeList |%{[regex]::转义($)})-加入“|”
    ,以防在其中一个被排除的字符串中有任何保留字符。@TheMadTechnician-在第一个字符串中对
    ^
    进行重击。有什么办法可以避免吗?@mklement0-谢谢你[咧嘴笑]。。。我将不提
    [regex]::Escape()
    ,谢谢。你是对的,这会起作用,但是有没有办法将正则表达式字符串定义为一个与“-match”(而不是“-notmatch”)一起工作的字符串?原因是我从配置文件(json)中读取了该正则表达式字符串以及许多其他正则表达式字符串,并且不是所有的正则表达式字符串都是“notmatches”“@MichaelHellmann-如果您在豪华环境中进行此操作,您可以根据需要链接任意多个
    -match
    &
    -notmatch
    操作。[grin]为了安全起见,当我这样做时,我通常会对字符串进行转义,例如:
    $regexcludelist=($ExcludeList |%{[regex]::转义($)})-连接“|”
    ,以防其中一个被排除的字符串中有任何保留字符@