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

1hdlvixo  于 2023-03-18  发布在  Shell
关注(0)|答案(7)|浏览(282)

我试着用一个分隔符来拆分这个字符串,它是一个字符串:

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

分裂的结果是:

5637144576, messag

est


5637145326, 1


5637145328, 0

代替

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

当我尝试使用接受string[]的重载split时:

$string = "5637144576, messag<>est<<>>5637145326, 1<<>>5637145328, 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.""

有人知道怎么一串一串地拆分吗?

5lwkijsr

5lwkijsr1#

-split运算符使用字符串进行拆分,而不是像Split()那样使用字符数组:

$string = "5637144576, messag<>est<<>>5637145326, 1<<>>5637145328, 0"
$separator = "<<>>"
$string -split $separator

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

如果你想用Split()方法处理一个字符串,你需要$seperator是一个只有一个元素的stringarray,并且指定一个stringsplitoptions值,你可以通过检查它的定义来了解这一点:

$string.Split

OverloadDefinitions                                                                                
-------------------                                                                                
string[] Split(Params char[] separator)                                                            
string[] Split(char[] separator, int count)                                                        
string[] Split(char[] separator, System.StringSplitOptions options)                                
string[] Split(char[] separator, int count, System.StringSplitOptions options)                     

#This one
string[] Split(string[] separator, System.StringSplitOptions options)      
string[] Split(string[] separator, int count, System.StringSplitOptions options)

$string = "5637144576, messag<>est<<>>5637145326, 1<<>>5637145328, 0"
$separator = [string[]]@("<<>>")
$string.Split($separator, [System.StringSplitOptions]::RemoveEmptyEntries)

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

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

$separator = "<<>>"
$string -split $separator, 0, "simplematch"

了解更多关于-splithere的信息。

vdgimpew

vdgimpew2#

你可以使用split运算符来代替Split方法,所以你的代码如下:

$string -split '<<>>'
zlhcx6iw

zlhcx6iw3#

有时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")
}
s6fujrry

s6fujrry4#

编辑日期:2020年5月23日:我已经把代码移到了GitHub,在这里,我做了一些更新来覆盖一些边缘情况:https://github.com/franklesniak/PowerShell_Resources/blob/master/Split-StringOnLiteralString.ps1
您可以使用-split运算符,但它要求使用RegEx。此外,-split运算符仅在Windows PowerShell v3+上可用,因此,如果您想要与PowerShell的所有版本普遍兼容,则需要使用不同的方法。
一个[regex]对象有一个Split()方法也可以处理这个问题,但是它需要RegEx作为“splitter”。为了解决这个问题,我们可以使用第二个[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

伏拉!

fnvucqvd

fnvucqvd5#

以下内容应该是您所需要的:

$string -Split $separator

这产生:

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

vwoqyblh6#

当我声明一个字符串时,这个方法很有效。当从一个文件中获取内容时,这个方法并不像预期的那样工作。你可以在一个文件中用同样的内容来尝试这个方法。

k3bvogb1

k3bvogb17#

这在powershell7中是有效的。

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

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

Powershell7实际上有一个新的.split()重载,它更接近于字符串作为第一个参数。令人惊讶的是,选项的第二个参数可以省略,使用默认的“None”值。

public string[] Split (string? separator, 
  StringSplitOptions options = System.StringSplitOptions.None);

系统字符串拆分(系统字符串拆分选项)

相关问题