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

风流意气都作罢 提交于 2019-12-12 15:55:43

问题


What's going on here?

issue.CallAction has the following value:

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

Splitting on it, like so:

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

returns more than 1 string element (as expected in this case) but the elements are:

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

It was my understanding that Split replaces the entire string that you're splitting yet it's only replacing the first letter.

What gives?

Here's a screenshot of the compiler being happy with a string separator. Note the absence of the angry red squiggle:

:


回答1:


It looks like it's treating the separator as a Char. At least in Visual Studio 2017/.NET 4.5,C# which is what I'm using, as well as the current version there is no

string Split(string separator)

so you'd have to create an array of separators and populate the first one.

Try this:

        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);

EDIT:

I haven't used VB in several years, so I had to do some re-learning here. The output of this sample program tells me that VB quietly coerces a String into a Char when a Char is called for:

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

See @Heinzi's important comment below for a best practice.




回答2:


To get compile error you can turn Option Strict On.

To split by string in VB.Net, you can use Microsoft.VisualBasic.Strings.Split:

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



回答3:


Isn't it interesting how the same code can appear to be both valid C# and VB.NET yet produce drastically different results? I did notice the lack of a trailing semicolon but assumed it was just a copy-and-paste artifact.

Using the following code...

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 indicates that the String.Split(ParamArray() separator as Char()) overload is being called (the MSDN documentation includes the ParamArray modifier)...

Upon execution list1 then contains the following:

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

If you write it using this seemingly-equivalent syntax...

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 indicates both .Split() calls are resolving to the same overload as above, yet the results for list2 are very different...

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

...and the same for list3. This is actually what we should have expected list1 to be all along since it would split on any one of the characters in the passed String.

Why is this happening? This is interesting to me, though I am not a VB.NET guy so perhaps this is common knowledge/pitfall. If we take a look at what the compiler produces we see this:

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)()

That is, in the case of list2 it is passing a Char array consisting of all of the Chars in "Containers remaining changed to ", yet in the case of list1 it is passing a Char array consisting of only the first Char, "C"c! Talk about different results from similar-looking code...

I can't find a single document that connects all of these dots, but, basically, String will be implicitly converted to Char(), which calls the CChar conversion function, which returns only the first Char. Thus, the following four lines are equivalent:

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()


来源:https://stackoverflow.com/questions/46330993/string-split-is-not-removing-the-split-text-only-the-first-letter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!