来自String.Split()的奇怪结果

时间:2016-11-04 03:45:15

标签: powershell

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

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

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

<#

Outputs:

7



RAH,


RAC

#>

4 个答案:

答案 0 :(得分:3)

为了字符串(而不是字符集)和/或正则表达式进行拆分,请使用PowerShell&# 39; s -split运算符

PS> ('OU=RAH,OU=RAC' -split ',?OU=') -ne ''  # parentheses not strictly needed
RAH
RAC
    默认情况下,
  • -split将其RHS解释为正则表达式,?OU=OU,OU本身匹配,-split,导致所需的拆分,将令牌作为数组返回。

    • 对于-split支持的所有功能,包括文字字符串匹配,限制返回的令牌数量以及脚本块的使用,请参阅Get-Help about_split
  • 由于输入以匹配方式启动,因此-ne ''会将拆分的第一个元素视为空字符串。通过将生成的标记数组传递给'OU=RAH,OU=RAC'.Split('OU=') ,我们会过滤掉这些空字符串。

相比之下,正如您所尝试的那样,使用 .NET String.Split() method 的方式非常不同:

OU=

@( '', '', '', 'RAH,', '', '', 'RAC')解释为字符数组任何,其中单独充当分隔符 - 与指定字符的顺序无关。默认情况下,前导,相邻和尾随分隔符会将空标记分开,因此您将获得 7 标记的数组:
String.Split()

对PowerShell Core 用户的注意事项:.NET Core [string]方法现在确实有一个标量{{ 1}}重载,查找整个字符串作为分隔符,PowerShell Core默认选择 ;要获得描述的字符数组行为,您必须明确地转换为[char[]]
'OU=RAH,OU=RAC'.Split([char[]] 'OU=')

如果您仔细构建.Split()方法调用,可以指定字符串,但请注意,您仍然无法定期 -expression 支持:

> 'OU=RAH,OU=RAC'.split([string[]] 'OU=', 'RemoveEmptyEntries')
RAH,
RAC

可以通过文字字符串 OU=进行拆分,删​​除空条目,但正如您所看到的,这不允许您考虑, < / p>

您可以通过指定要拆分的字符串的数组来进一步实现这一点,这可以在这个简单的情况下工作,但最终并没有提供与PowerShell&的正则表达式相同的灵活性#39; s -split运营商提供:

> 'OU=RAH,OU=RAC'.split([string[]] ('OU=', ',OU='), 'RemoveEmptyEntries')
RAH
RAC

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

答案 1 :(得分:2)

它会拆分分隔符中每个字符的字符串。所以它把它分成'O','U'和&amp; '='。

正如@ mklement0所评论的那样,我之前的回答并不适用于所有情况。所以这是另一种获得预期项目的方法。

$a.Split(',') |% { $_.Split('=') |? { $_ -ne 'OU' } }

此代码将首先在,上拆分字符串,然后将每个项目拆分为=并忽略OU项,最终返回预期值:

RAH
RAC

即使出现以下情况,这也会有效:

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

生成3个项目FOORAH&amp; RAC

要获得预期的2个字符串,可以使用以下行: $ a.Split('OU =',[System.StringSplitOptions] :: RemoveEmptyEntries) 这将输出为: RAH, RAC 如果你使用(注意分隔符中的逗号) $ a.Split(',OU =',[System.StringSplitOptions] :: RemoveEmptyEntries) 你会得到 RAH RAC

这可能是你想要的。 :)

答案 2 :(得分:1)

没关系。刚刚意识到它在“O”,“U”和“=”两侧寻找字符串。 因此有5个空白字符(在第一个'O'之前,在'O'和'U'之间,在'U'和'='之间,在第二个'O'和'U'之间,在第二个'U之间) '和'=')。

答案 3 :(得分:1)

String.Split()是面向字符的。它在OU=上分为三个不同的位置。

将其视为打算用于1,2,3,4,5。如果你有,2,3,4,,则意味着在开始和结束时都有空格。如果你有1,2,,,5,则意味着中间有两个空格。

您可以看到类似的内容:

PS C:\> $a = 'OU=RAH,OU=RAC'
PS C:\> $a.Split('RAH')
OU=


,OU=

C

空格为R_A_HR_A。在字符串末尾分割,它在开头/结尾引入空格。

PowerShell的-split运算符是面向字符串的。

PS D:\t> $a = 'OU=RAH,OU=RAC'

PS D:\t> $a -split 'OU='

RAH,
RAC

你可能最好分开逗号,然后替换OU =,反之亦然,例如

PS D:\t> $a = 'OU=RAH,OU=RAC'

PS D:\t> $a.Replace('OU=','').Split(',')
RAH
RAC