String.Split() 的奇怪结果

Bac*_*ave 3 powershell

为什么以下结果会产生一个包含 7 个元素和 5 个空白的数组?我希望只有 2 个元素。5个空白元素来自哪里?

$a = 'OU=RAH,OU=RAC'

$b = $a.Split('OU=')
$b.Count 
$b

<#

Outputs:

7



RAH,


RAC

#>
Run Code Online (Sandbox Code Playgroud)

mkl*_*nt0 7

为了字符串(而不是一组字符)和/或正则表达式进行拆分,请使用 PowerShell 的-split运算符

PS> ('OU=RAH,OU=RAC' -split ',?OU=') -ne ''  # parentheses not strictly needed
RAH
RAC
Run Code Online (Sandbox Code Playgroud)
  • -split默认情况下,将其 RHS 解释为正则表达式,并同时,?OU=匹配OU,OU,从而产生所需的拆分,将标记作为数组返回。

    • 有关 支持的所有功能-split,包括文字字符串匹配、限制返回的标记数量以及脚本块的使用,请参阅Get-Help about_split
  • 但是,由于输入以匹配开始,因此-split将拆分的第一个元素视为空字符串。通过将生成的令牌数组传递给-ne '',我们过滤掉了这些空字符串。


相比之下,Windows PowerShell 中使用.NET (FullCLR, up to 4.x) String.Split()method,正如您所尝试的,工作方式非常不同:

'OU=RAH,OU=RAC'.Split('OU=')
Run Code Online (Sandbox Code Playgroud)

OU=解释为一个阵列的字符任何其中,单独地充当分离器-不论在其中指定的字符的顺序。默认情况下,前导、相邻和尾随分隔符被视为分隔空标记,因此您会得到一个包含7 个标记的数组:
@( '', '', '', 'RAH,', '', '', 'RAC')

PowerShell Core用户注意事项(PowerShell 6 及以上版本):.NET Core String.Split()方法现在确实有一个标量[string]重载,它会查找整个字符串作为分隔符,PowerShell Core默认选择该分隔符;要获得描述的字符数组行为,您必须[char[]]显式转换为:
'OU=RAH,OU=RAC'.Split([char[]] 'OU=')


如果.Split()仔细构造方法调用,则可以指定strings,但请注意,您仍然无法获得正则表达式支持:

PS> 'OU=RAH,OU=RAC'.Split([string[]] 'OU=', 'RemoveEmptyEntries')
RAH,
RAC
Run Code Online (Sandbox Code Playgroud)

可以按文字 string 拆分OU=,删除空条目,但正如您所看到的,这不允许您考虑,

您可以通过指定要拆分的字符串数组来进一步实现这一点,这在这种简单的情况下有效,但最终不会为您-split提供与 PowerShell运算符提供的正则表达式相同的灵活性:

PS> 'OU=RAH,OU=RAC'.Split([string[]] ('OU=', ',OU='), 'RemoveEmptyEntries')
RAH
RAC
Run Code Online (Sandbox Code Playgroud)

请注意,指定一个(数组)字符串需要方法调用的2参数形式,这意味着您还必须指定一个System.StringSplitOptions枚举值。使用'None'不应用任何选项(在写本,即支持是唯一真正的选项'RemoveEmptyEntries',如上面使用)。
(指定选项的类型安全方法是使用,例如,,[System.StringSplitOptions]::None但是,将选项名称作为字符串传递是一种方便的快捷方式;例如,'None'。)