String.Split() 使用 VbCrLf 不起作用,但先用 "" 替换 VbCr 然后拆分 VbLf 才起作用。为什么?

String.Split() using VbCrLf doesn't work but replacing VbCr with "" first then splitting on VbLf does work. Why?

我有一个嵌入的文本文件作为资源。内容为:

Apple
Pear
Orange

我正试图将它拉入 List(Of String),但是回车符 Return 和换行符把它弄乱了。
例如我试试这个:

Dim myNames As List(Of String) = My.Resources.TreeNames.Split(CChar(vbCrLf)).ToList

但是正在传递换行符:

"Apple"
vbLf & "Pear"
vbLf & "Orange"

所以我尝试使用环境变量:

Dim myNames As List(Of String) = My.Resources.TreeNames.Split(CChar(Environment.NewLine)).ToList

但这会产生完全相同的输出。
所以我尝试在换行符上拆分它:

Dim myNames As List(Of String) = My.Resources.TreeNames.Split(CChar(vbLf)).ToList

现在正在传递回车 return 字符:

"Apple" & vbCr
"Pear" & vbCr
"Orange"

所以我让它工作的唯一方法是首先将 vbCr 替换为空,然后在左侧拆分 vbLf:

Dim myNames As List(Of String) = Replace(My.Resources.TreeNames, vbCr, "").Split(CChar(vbLf)).ToList

谁能解释一下为什么?如果我使用以下方法将文件直接拉入字符串:

Dim myNames as String = My.Resources.TreeNames

我得到:

"Apple" & vbCrLf & "Pear" & vbCrLf & "Orange"

为什么拆分不能正常工作?

查看有关 CChar(<expression>) 的文档:

Any valid Char or String expression; only first character of a String is converted; value can be 0 through 65535 (unsigned)

所以 CChar(vbCrLf) returns 只是 VbCr (\r - &H0D)

由于您现在仅在 VbCr 上拆分源字符串,换行符 VbLf (\n - &H0A) 仍然存在。

您需要接受字符串或字符数组的 String.Split() 重载:
注意vbCrLf是字符串类型,VbCrVbLf

也是
Dim res = My.Resources.TreeNames
' As an array of String
Dim myNames = res.Split({vbCrLf}, StringSplitOptions.RemoveEmptyEntries).ToList()
'Or
Dim myNames = res.Split({vbCr, VbLf}, StringSplitOptions.RemoveEmptyEntries).ToList()

或作为字符数组:

Dim myNames = res.Split(vbCrLf.ToCharArray(), StringSplitOptions.RemoveEmptyEntries).ToList()
' Or
Dim myNames = res.Split({ChrW(13), ChrW(10)}, StringSplitOptions.RemoveEmptyEntries).ToList()

StringSplitOptions.RemoveEmptyEntries 用于去除拆分多个连续字符产生的空行。
没有它,使用您的示例字符串 - 由 Carriage Return + Line Feed 分隔的 3 个项目 - 您将得到一个包含 5 个元素而不是 3 个元素的数组,包括 2 个空元素。

我不推荐使用 VB 常量。相反,您应该使用 Environment.NewLine 属性:https://docs.microsoft.com/en-us/dotnet/api/system.environment.newline

根据文档:

The property value of NewLine is a constant customized specifically for the current platform and implementation of the .NET Framework.

用法:

Dim myNames = My.Resources.TreeNames.Split(Environment.NewLine)

当然,您可以完全跳过 .Split,直接

Dim LinesList = File.ReadAllLines("txtFruit.txt").ToList

使用 Option Infer 将光标悬停在 LinesList 上,您将看到它是一个强类型 List(Of String)