如何在Powershell中逐个拆分字符串

如何在Powershell中逐个拆分字符串,powershell,Powershell,我正在尝试使用分隔符吐出字符串,这是一个字符串: $string = "5637144576, messag<>est<<>>5637145326, 1<<>>5637145328, 0" $separator = "<<>>" $string.Split($separator) 而不是 5637144576, messag<>est 5637145326, 1 5637145328, 0 563

我正在尝试使用分隔符吐出字符串,这是一个字符串:

$string = "5637144576, messag<>est<<>>5637145326, 1<<>>5637145328, 0"
$separator = "<<>>"
$string.Split($separator)
而不是

5637144576, messag<>est
5637145326, 1
5637145328, 0
5637144576,messagest
5637145326, 1
5637145328, 0
当我尝试使用接受字符串[]的重载拆分时:

$string = "5637144576, messag<>est<<>>5637145326, 1<<>>5637145328, 0"
$separator = @("<<>>")
$string.Split($separator)
$string=“5637144576,messagest5637145326,15637145328,0”
$separator=@(“”)
$string.Split($separator)
但我得到了下一个错误:

Cannot convert argument "0", with value: "System.Object[]", for "Split" to type "System.Char[]": "Cannot convert value "<<>>" to type "System.Char". Error: "String must be exactly one character long.""
无法将值为“System.Object[]”的用于“Split”的参数“0”转换为类型“System.Char[]”:“无法将值”转换为类型“System.Char”。错误:“字符串长度必须正好是一个字符。”

有人知道如何按字符串拆分字符串吗?

-split
操作符使用字符串进行拆分,而不是像
split()
这样的字符:

编辑:正如@RomanKuzmin指出的,
-split
默认使用正则表达式模式进行拆分。因此,请注意转义特殊字符(例如,在正则表达式中是“任意字符”)。您还可以强制
simplematch
禁用正则表达式匹配,如:

$separator = "<<>>"
$string -split $separator, 0, "simplematch"
$separator=“”
$string-拆分$separator,0,“simplematch”

阅读有关
-split
的更多信息使用
split
方法时,您可以使用
split
操作符。因此,您的代码如下所示:

$string -split '<<>>'
$string-拆分“”

以下是您需要的:

 $string -Split $separator
这将产生:

5637144576, messag<>est
5637145326, 1
5637145328, 0
5637144576,messagest
5637145326, 1
5637145328, 0

有时PowerShell看起来就像C#而在其他情况下,您知道

也可以这样使用:

# A dummy text file
$text = @'
abc=3135066977,8701416400

def=8763026853,6433607660

xyz=3135066977,9878763344
'@ -split [Environment]::NewLine,[StringSplitOptions]"RemoveEmptyEntries"

"`nBefore `n------`n"

$text

"`nAfter `n-----`n"

# Do whatever with this
foreach ($line in $text)
{
    $line.Replace("3135066977","6660985845")
}

编辑2020-05-23:我已将代码移到GitHub,在这里,我进行了更新,以涵盖一些边缘情况:


可以使用-split操作符,但它需要正则表达式。此外,-split运算符仅在Windows PowerShell v3+上可用,因此如果您想要与所有版本的PowerShell兼容,我们需要一种不同的方法

[regex]对象有一个Split()方法也可以处理这个问题,但它同样希望regex作为“拆分器”。为了解决这个问题,我们可以使用第二个[regex]对象并调用Escape()方法将文本字符串“splitter”转换为转义的regex

将所有这些都打包成一个易于使用的函数,该函数可以回溯到PowerShell v1,也可以回溯到PowerShell Core 6.x

function Split-StringOnLiteralString
{
    trap
    {
        Write-Error "An error occurred using the Split-StringOnLiteralString function. This was most likely caused by the arguments supplied not being strings"
    }

    if ($args.Length -ne 2) `
    {
        Write-Error "Split-StringOnLiteralString was called without supplying two arguments. The first argument should be the string to be split, and the second should be the string or character on which to split the string."
    } `
    else `
    {
        if (($args[0]).GetType().Name -ne "String") `
        {
            Write-Warning "The first argument supplied to Split-StringOnLiteralString was not a string. It will be attempted to be converted to a string. To avoid this warning, cast arguments to a string before calling Split-StringOnLiteralString."
            $strToSplit = [string]$args[0]
        } `
        else `
        {
            $strToSplit = $args[0]
        }

        if ((($args[1]).GetType().Name -ne "String") -and (($args[1]).GetType().Name -ne "Char")) `
        {
            Write-Warning "The second argument supplied to Split-StringOnLiteralString was not a string. It will be attempted to be converted to a string. To avoid this warning, cast arguments to a string before calling Split-StringOnLiteralString."
            $strSplitter = [string]$args[1]
        } `
        elseif (($args[1]).GetType().Name -eq "Char") `
        {
            $strSplitter = [string]$args[1]
        } `
        else `
        {
            $strSplitter = $args[1]
        }

        $strSplitterInRegEx = [regex]::Escape($strSplitter)

        [regex]::Split($strToSplit, $strSplitterInRegEx)
    }
}
现在,使用前面的示例:

PS C:\Users\username> Split-StringOnLiteralString "5637144576, messag<>est<<>>5637145326, 1<<>>5637145328, 0" "<<>>"
5637144576, messag<>est
5637145326, 1
5637145328, 0
PS C:\Users\username>Split-StringOnLiteralString“5637144576,messagest563714532615637145328,0”
5637144576,messagest
5637145326, 1
5637145328, 0

沃拉

为什么分隔符应沿
拆分?为什么分隔符应沿
拆分这是我面临并试图解决的一个问题,您是否希望沿
的任何字符分割?
est
应该保留。他似乎想用
的任何字符分割(即沿着
)sry,在您想要的输出样本中没有看到est^^请参阅更新的答案您知道吗,可能只返回非空字符串?请参阅上次更新。它还解释了
Split()
methods行为“该-Split运算符使用文本字符串进行拆分”--默认情况下,-Split运算符使用正则表达式(不带SimpleMatch选项)。在这个例子中,这并不重要,但一般来说是重要的。
# A dummy text file
$text = @'
abc=3135066977,8701416400

def=8763026853,6433607660

xyz=3135066977,9878763344
'@ -split [Environment]::NewLine,[StringSplitOptions]"RemoveEmptyEntries"

"`nBefore `n------`n"

$text

"`nAfter `n-----`n"

# Do whatever with this
foreach ($line in $text)
{
    $line.Replace("3135066977","6660985845")
}
function Split-StringOnLiteralString
{
    trap
    {
        Write-Error "An error occurred using the Split-StringOnLiteralString function. This was most likely caused by the arguments supplied not being strings"
    }

    if ($args.Length -ne 2) `
    {
        Write-Error "Split-StringOnLiteralString was called without supplying two arguments. The first argument should be the string to be split, and the second should be the string or character on which to split the string."
    } `
    else `
    {
        if (($args[0]).GetType().Name -ne "String") `
        {
            Write-Warning "The first argument supplied to Split-StringOnLiteralString was not a string. It will be attempted to be converted to a string. To avoid this warning, cast arguments to a string before calling Split-StringOnLiteralString."
            $strToSplit = [string]$args[0]
        } `
        else `
        {
            $strToSplit = $args[0]
        }

        if ((($args[1]).GetType().Name -ne "String") -and (($args[1]).GetType().Name -ne "Char")) `
        {
            Write-Warning "The second argument supplied to Split-StringOnLiteralString was not a string. It will be attempted to be converted to a string. To avoid this warning, cast arguments to a string before calling Split-StringOnLiteralString."
            $strSplitter = [string]$args[1]
        } `
        elseif (($args[1]).GetType().Name -eq "Char") `
        {
            $strSplitter = [string]$args[1]
        } `
        else `
        {
            $strSplitter = $args[1]
        }

        $strSplitterInRegEx = [regex]::Escape($strSplitter)

        [regex]::Split($strToSplit, $strSplitterInRegEx)
    }
}
PS C:\Users\username> Split-StringOnLiteralString "5637144576, messag<>est<<>>5637145326, 1<<>>5637145328, 0" "<<>>"
5637144576, messag<>est
5637145326, 1
5637145328, 0