String.Split 不删除拆分文本,只删除第一个字母

String.Split is not removing the split text, only the first letter

这是怎么回事?

issue.CallAction 具有以下值:

"Blah blah - WebSite - 9/20/2017 - Containers remaining changed to 0."

在上面拆分,像这样:

issue.CallAction.Split("Containers remaining changed to ").ToList()

returns 超过 1 个字符串元素(在本例中符合预期)但元素是:

  1. Blah blah - WebSite - 9/20/2017 -
  2. ontainers remaining changed to 0.

据我了解,Split 替换了您要拆分的整个字符串,但它仅替换了第一个字母。

什么给了?

这是编译器对字符串分隔符满意的屏幕截图。注意没有愤怒的红色波浪线:

:

它似乎将分隔符视为 Char。至少在 Visual Studio 2017/.NET 4.5,我正在使用的 C# 以及 the current version 中没有

string Split(string separator)

因此您必须创建一个分隔符数组并填充第一个分隔符。

试试这个:

        string s = "Blah blah - WebSite - 9/20/2017 - Containers remaining changed to 0.";

        string[] separator = { "Containers remaining changed to " };
        string[] splitted = s.Split(separator, StringSplitOptions.None);

编辑:

我好几年没用过VB了,所以我不得不在这里重新学习一下。这个示例程序的输出告诉我 VB 在调用 Char 时悄悄地将 String 强制转换为 Char

Sub PrintAChar(c As Char)
    Console.WriteLine("Printing your character: '" + c + "'")
End Sub

Sub Main()
    PrintAChar("B")                ' Prints 'B'
    PrintAChar("Bob Was Here.")    ' Also prints 'B'
End Sub

请参阅下面@Heinzi 的重要评论以获得最佳实践。

同样的代码看起来既是有效的 C# 又是 VB.NET 却产生截然不同的结果,这不是很有趣吗?我确实注意到缺少尾随分号,但假设它只是一个复制粘贴的产物。

使用以下代码...

Dim text As String = "Blah blah - WebSite - 9/20/2017 - Containers remaining changed to 0."
Dim list1 As List(Of String) = text.Split("Containers remaining changed to ").ToList()

...IntelliSense 指示 String.Split(ParamArray() separator as Char()) overload is being called (the MSDN documentation 包含 ParamArray 修饰符)...

执行后 list1 然后包含以下内容:

list1(0) = "Blah blah - WebSite - 9/20/2017 - "
list1(1) = "ontainers remaining changed to 0."

如果您使用这种看似等效的语法编写它...

Dim list2 As List(Of String) = text.Split("C", "o", "n", "t", "a", "i", "n", "e", "r", "s", " ", "r", "e", "m", "a", "i", "n", "i", "n", "g", " ", "c", "h", "a", "n", "g", "e", "d", " ", "t", "o", " ").ToList()
Dim list3 As List(Of String) = text.Split("Containers remaining changed to ".ToCharArray()).ToList()

...IntelliSense 指示两个 .Split() 调用都解析为与上述相同的重载,但 list2 的结果非常不同...

list2(0)  = "Bl"
list2(1)  = ""
list2(2)  = ""
list2(3)  = "bl"
list2(4)  = ""
list2(5)  = ""
list2(6)  = "-"
list2(7)  = "W"
list2(8)  = "bS"
list2(9)  = ""
list2(10) = ""
list2(11) = ""
list2(12) = "-"
list2(13) = "9/20/2017"
list2(14) = "-"
list2(15) = ""
list2(16) = ""
list2(17) = ""
list2(18) = ""
list2(19) = ""
list2(20) = ""
list2(21) = ""
list2(22) = ""
list2(23) = ""
list2(24) = ""
list2(25) = ""
list2(26) = ""
list2(27) = ""
list2(28) = ""
list2(29) = ""
list2(30) = ""
list2(31) = ""
list2(32) = ""
list2(33) = ""
list2(34) = ""
list2(35) = ""
list2(36) = ""
list2(37) = ""
list2(38) = ""
list2(39) = ""
list2(40) = ""
list2(41) = ""
list2(42) = ""
list2(43) = ""
list2(44) = ""
list2(45) = ""
list2(46) = ""
list2(47) = "0."

...list3 也是如此。这实际上是我们应该一直期望 list1 的结果,因为它会在传递的 String.

中的任何一个字符上拆分

为什么会这样?这对我来说很有趣,虽然我不是 VB.NET 人,所以也许这很常见 knowledge/pitfall。如果我们看一下 what the compiler produces,我们会看到:

Dim text As String = "Blah blah - WebSite - 9/20/2017 - Containers remaining changed to 0."
Dim arg_13_0 As String = text
Dim expr_0E As Char() = New Char(0) {}
expr_0E(0) = "C"c
Dim list As List(Of String) = arg_13_0.Split(expr_0E).ToList(Of String)()
Dim arg_31_0 As String = text
Dim expr_26 As Char() = New Char(31) {}
RuntimeHelpers.InitializeArray(expr_26, fieldof(<PrivateImplementationDetails>.B46FB904AE74F7001A264BB77882D707B0E9ECC7).FieldHandle)
Dim list2 As List(Of String) = arg_31_0.Split(expr_26).ToList(Of String)()
Dim list3 As List(Of String) = text.Split("Containers remaining changed to ".ToCharArray()).ToList(Of String)()

也就是说,在 list2 的情况下,它正在传递一个 Char 数组,该数组由 "Containers remaining changed to " 中的所有 Char 组成,但在 "Containers remaining changed to " 的情况下list1 它正在传递一个仅由第一个 Char"C"c 组成的 Char 数组!讨论相似代码的不同结果...

我找不到连接所有这些点的单个文档,但是,基本上,String 将是 implicitly converted to Char(), which calls the CChar conversion function,returns 只是第一个 Char.因此,以下四行是等价的:

Dim list1a As List(Of String) = text.Split("Containers remaining changed to ").ToList()
Dim list1b As List(Of String) = text.Split(CChar("Containers remaining changed to ")).ToList()
Dim list1c As List(Of String) = text.Split("C").ToList()
Dim list1d As List(Of String) = text.Split("C"c).ToList()

要得到编译错误你可以转 Option Strict On.

要在 VB.Net 中按字符串拆分,您可以使用 Microsoft.VisualBasic.Strings.Split:

Dim result = Split(issue.CallAction, "Containers remaining changed to ")