用于字符串中可选等号分隔符的 Powershell 正则表达式

hsb*_*tra 2 powershell regex-group

在下面的测试字符串中,键和值之间可以有一个等号一个或多个空格字符。如果存在等号,则它可以可选地前面和/或后面有零个或多个空格字符。

$MyTstString = "KeyX =  ValueY"
$RegExString = "^(?<Key>.+)(?<Sep>\s*=\s*)(?<Value>.*)$"
$MyTstString -match $RegExString | Foreach {$Matches}
Run Code Online (Sandbox Code Playgroud)

什么正则表达式会为我做到这一点?

将 RegExString 更改为

$RegExString = "^(?<Key>.+)(?<Sep>\s*=\s*|\s+)(?<Value>.*)$"
Run Code Online (Sandbox Code Playgroud)

当 TestString 为“KeyA = ValueB”时,会导致 Key 和 Sep 不正确

mkl*_*nt0 5

注意:\s匹配所有形式的空格,而不仅仅是空格,包括制表符、换行符、... 要将匹配限制为仅空格,请使用逐字空格 ( ) 代替\s下面的空格。


我建议使用-split多分配相结合操作

$key, $value = $MyTstString -split '\s*=\s*|\s+', 2
Run Code Online (Sandbox Code Playgroud)

注意:, 2部分(指定可选<Max-strings>操作数)确保最多只返回两个标记;否则,值部分可能最终本身得到分手了,如果它恰好包含空格或=。谢谢,

如果您还想捕获分隔符字符串:

$key, $sep, $value = $MyTstString -split '(\s*=\s*|\s+)', 2
Run Code Online (Sandbox Code Playgroud)

至于你尝试什么

正如Bender the Greatest指出的那样,一个-match带有标量LHS的操作:

  • 返回 $true$false指示正则表达式是否匹配。
  • 如果它确实匹配,则用它找到的 - 一个 - 匹配填充自动$Matches变量(它永远不会寻找更多)。

(与此相反,与一个阵列(集合)为LHS,-match返回(可能是空的)匹配元素的子阵列,并且也没有填充$Matches)。

使用您的原始方法,以及更正和简化的正则表达式形式:

  • 您的正则表达式(两种变体)的问题(?<Key>.+)过于贪婪,并且在捕获组匹配中包含前面=或最后一个空格

  • 最简单的办法是简单地+量词非贪婪(?<Key>.+?); 或者,将匹配的字符限制为除空格和=: 之外的所有字符
    (?<Key>[^\s=]+)

$RegExString = '^(?<Key>.+?)(?<Sep>\s*=\s*|\s+)(?<Value>.*)$'

'KeyX1 =  ValueY1', 'KeyX2 ValueY2', 'KeyX3=ValueY3' | 
  ForEach-Object {
    if ($_ -match $RegExString) {
      [pscustomobject] @{ Key = $Matches.Key; Sep = $Matches.Sep; Value = $Matches.Value}
    }
  }
Run Code Online (Sandbox Code Playgroud)

以上产生:

$key, $sep, $value = $MyTstString -split '(\s*=\s*|\s+)', 2
Run Code Online (Sandbox Code Playgroud)