【问题标题】:How to split string by string in Powershell如何在Powershell中逐个字符串拆分
【发布时间】:2020-05-23 23:32:31
【问题描述】:

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

$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[] 的重载拆分时:

$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.""

有人知道如何逐个字符串分割吗?

【问题讨论】:

  • 为什么分隔符&lt;&lt;&gt;&gt;要沿&lt;&gt;拆分?
  • 为什么分隔符>要沿分开? - 这是我面临并试图解决的问题
  • 你想沿任何字符 &lt;&lt;&gt;&gt;分割吗?

标签: powershell


【解决方案1】:

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

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

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

如果要对字符串使用Split() 方法,则需要$seperator 是一个包含一个元素的字符串数组,并指定一个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的信息。

【讨论】:

  • est 应该被保留。他似乎想被&lt;&lt;&gt;&gt;的任何字符分割(即沿着&lt;&gt;
  • sry,在您想要的输出示例中没有看到 est ^^ 查看更新的答案
  • 你知道吗,有可能只返回非空字符串吗?
  • 查看最新更新。它也解释了 Split() 方法的行为
  • "-split 运算符使用文字字符串进行拆分" -- -split 运算符默认使用正则表达式(没有 SimpleMatch 选项)。在这个例子中,这无关紧要,但一般来说确实如此。
【解决方案2】:

不使用Split 方法,您可以使用split 运算符。所以你的代码会是这样的:

$string -split '<<>>'

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      编辑 2020-05-23:我已将代码移至 GitHub,在这里我进行了更新以涵盖一些边缘情况:https://github.com/franklesniak/PowerShell_Resources/blob/master/Split-StringOnLiteralString.ps1


      您可以使用 -split 运算符,但它需要 RegEx。此外,-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
      

      沃拉!

      【讨论】:

        【解决方案5】:

        以下应该是您需要的:

         $string -Split $separator
        

        这会产生:

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

        【讨论】:

          猜你喜欢
          • 2016-01-09
          • 2014-07-27
          • 2019-12-16
          • 1970-01-01
          • 2018-08-08
          • 2016-02-21
          • 1970-01-01
          • 1970-01-01
          • 2019-04-21
          相关资源
          最近更新 更多