【问题标题】:Split a string without separators in PowerShell在 PowerShell 中拆分不带分隔符的字符串
【发布时间】:2016-09-04 21:05:54
【问题描述】:

我想拆分一个字符串并将生成的标记存储在变量中。

例如,我的字符串是160519,我想将其拆分为160519 存储在单独的变量中。

我尝试使用-split,但由于我的字符串没有分隔符,我发现很难剪切字符串。

【问题讨论】:

标签: string powershell split powershell-2.0


【解决方案1】:

如果您使用正则表达式,您实际上可以像这样拆分字符串。

$arr = $string -split "(..)" -ne ""

. 匹配任何单个字符。然后我们需要过滤数组以删除空值,这是 -ne "" 出现的地方(感谢 mklement0 建议替换 | ? {$_})。

在行动:

C:\Users\Paarth> $string = "160519"
C:\Users\Paarth> $arr = $string -split "(..)" -ne ""
C:\Users\Paarth> $arr
16
05
19
C:\Users\Paarth>

【讨论】:

  • 这很漂亮。为什么会产生需要移除的空值?
  • 根据the docs,在有相邻匹配项的地方添加空字符串。这实际上是拆分一个字符串 提取一些正则表达式,但是一旦我们对此进行拆分,就什么都没有了,所以它可以工作。我们删除空字符串,只剩下数组中匹配的条目。
  • ++;虽然有些晦涩,但它是一个简洁的解决方案,具有使用可变数量的令牌的优势。我建议重新格式化为$arr = ('160519' -split '(..)') -ne '',由于避免了带有 cmdlet 调用的管道,因此效率更高。
  • @JasonBoyd:另一种说法:向正则表达式添加 捕获组 ((...)) 使-split 也捕获并返回分隔符;例如:'a.b:c' -split '([.:])' -> @( 'a', '.', 'b', ':', 'c' )。在这里,分隔符正则表达式的匹配会消耗整个字符串,它们之间只留下 empty 字段,必须清除这些字段。简而言之:这是对-split 的巧妙但有些晦涩的再利用:通常用于捕获分隔符的功能在这里用于捕获数据
  • 感谢@mklement0 的解释和建议,我已经用它更新了答案。
【解决方案2】:

如果您没有分隔符,则无法有效地使用-split。相反,你必须使用类似的东西:

$d = '160519'
$a, $b, $c = $d.SubString(0, 2), $d.SubString(2, 2), $d.SubString(4, 2)

# (That is like doing:
$a = $d.SubString(0, 2)
$b = $d.SubString(2, 2)
$c = $d.SubString(4, 2)
# but doing all three in one go )

停在这里,这就是你所需要的。 :-)


除此之外:您可以从一个字符串中索引多个字符,但它们作为单独的字符出现,并且每个字符都需要重新连接成字符串,所以它不是更整洁也不是更清晰:

$d = '160519'
$a, $b, $c = ($d[0..1] -join ''), ($d[2..3] -join ''), ($d[4..5] -join '')

[编辑:我想,如果你真的在乎,你可以强制 -split 为你工作,因为你可以用正则表达式描述两个数字。这样做的问题是,您通常会根据找到分隔符、丢弃分隔符并保留其余部分来进行拆分。如果你想保留分隔符,你可以用正则表达式组来做,但是 -split 会在它认为内容应该存在的地方输出空白空间,所以它需要一个丑陋的解决方法才能让它工作:

# split based on a regular expression describing two digits \d\d
# capture the digits in a group (\d\d)
# Filter the output through Where-Object   |?
# Only the numbers will pass, the empty space won't
$a, $b, $c = $d -split '(\d\d)' |? {$_}

或者使用 .Net [Regex] 库更标准地使用正则表达式:

$a, $b, $c = [Regex]::Matches($d, '\d\d') | Select -ExpandProperty Value

或在 PowerShell 中

$d -match '(\d\d)(\d\d)(\d\d)'
$a, $b, $c = $matches[1,2,3]

# hey, this one's pretty nice.

]

【讨论】:

  • 用正则表达式分割就可以了,看我的回答
  • ++;我同意最后一个相当不错 - 也许值得更突出地展示。
【解决方案3】:

试试这个

$text="160519"
$var0, $var1, $var2, $var3= $text -split "(\d{2})(\d{2})(\d{2})"
$var1
$var2
$var3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-31
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    相关资源
    最近更新 更多