如何拆分包含换行符的字符串

How to split a string containing newlines

一个字符串(从 Outlook 电子邮件 body.innerText 中提取)包含嵌入的换行符。如何将其拆分为字符串数组?

我希望这个示例字符串被分成两 (2) 个项目的数组。相反,它变成了一个包含三 (3) 个项目的数组,中间有一个空行。

PS C:\src\t> ("This is`r`na string.".Split([Environment]::NewLine)) | % { $_ }
This is

a string.
PS C:\src\t> "This is `r`na string.".Split([Environment]::NewLine) | Out-String | Format-Hex

           00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000   54 68 69 73 20 69 73 20 0D 0A 0D 0A 61 20 73 74  This is ....a st
00000010   72 69 6E 67 2E 0D 0A                             ring...

要将CRLF序列作为一个整体作为分隔符,使用-split 运算符更简单,它基于 regex:

PS> "This is `r`n`r`n a string." -split '\r?\n'
This is 
 a string.

注:

  • \r?\n 匹配 CRLF(Windows-style)和 LF-only(Unix-style)换行符;如果您真的只想匹配 CRLF 序列,请使用 \r\n

    • 注意使用 单引号 字符串 ('...'),以便将包含正则表达式的字符串按原样传递给 .NET 正则表达式引擎;正则表达式引擎使用 \ 作为转义字符;因此使用 \r\n.
  • PowerShell 的 -split operator 通常是 [string] .NET 类型的 .Split() 方法 - 见.


至于你试过的

Windows 上的分隔符参数 [Environment]::NewLine 是字符串 "`r`n",即 CRLF 序列。

  • PowerShell [Core] v6+ 中,您的命令 确实 有效,因为此字符串 作为一个整体被认为是分隔符。

  • Windows PowerShell 中,正如史蒂文在 中指出的那样, 单个字符 - CR 和 LF separately 被认为是分隔符,导致结果数组中有一个额外的空元素 - CR 和 LF 之间的空字符串。

这种行为变化发生在 PowerShell 的控制之外:.NET Core 引入了一个新的 .Split() 方法重载,带有 [string] 类型的分隔符参数,PowerShell 的重载解析算法现在选择使用 [char[]] 类型参数的旧重载。
避免这种不可避免(尽管很少见)的无意行为改变是另一个更喜欢 PowerShell-native -split operator 而不是 .NET [string] 类型的 .Split() 方法.

这是因为 .Split() 方法将拆分它找到的任何字符,例如:

"first part of a string-*second part of a string".Split("-*")

输出:

first part of a string

second part of a string

额外的元素是插入在 2 个拆分字符之间的空字符串。

(归功于@mklement0,用于更正)

所以我只能假设这是几个因素的结果。首先 [Environment]::NewLine 是字符 CarrigeReturn 和 LineFeed,来自 outlook 的行确实使用了该行结束序列。 Windows.

一切尽在意料之中

我能想到的解决方案有2种:

选项 1:

.Split([Environment]::NewLine), [Stringsplitoptions]::RemoveEmptyEntries)

这显然与相同的 .Split() 方法保持一致,但添加的参数会杀死额外的元素。

选项 2:

使用 PowerShell -split 运算符,它使用 RegEx 匹配分隔符:

"This is`r`na string." -split "`r`n"

你好,

I'm a big NooB in PowerShell, but ...
I ave wrote this

$str_1 ="This is

a string."
$splt_1=$str_1.Split()
$cnt_1=1
foreach ($item in $splt_1) {
     $regEx="[a-zA-Z]"
     if ($item -cmatch $regEx){
          $Result_1=$Result_1+"$item "
     } elseif ($cnt_1 -eq 1) {
          $Result_1=$Result_1+"| "
          $cnt_1=$cnt_1+1
     }
}
Write-Host $Result_1
## OUTPUT ##
# This is | a string.

$str_2="
This is

....a st

ring...
"
$splt_2=$str_2.Split()
$cnt_2=1
foreach ($item in $splt_2) {
     $regEx="[a-zA-Z]"
     if ($item -cmatch $regEx){
          $cnt_2=1
          $Result_2=$Result_2+"$item "
     } elseif ($cnt_2 -eq 1) {
          $Result_2=$Result_2+"| "
          $cnt_2=$cnt_2+1
     }
}
Write-Host $Result_2
## OUTPUT ##
# | This is | ....a st | ring... |

希望对您有所帮助...

PS:

才发现忘了结果.....


$Result_1.Split("|")
## OUTPUT ##
This is
 a string.

 $Result_2.Split("|")
 ## OUTPUT ##
 This is
 ....a st
 ring...

EOF

阿克塞尔埃里克。