Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

string IndexOf and Replace

Tags:

c#

.net

replace

I have just faced this problem today and wonder if someone has any idea about why does this test may fail (depending on culture). The aim is to check if the test text contain two spaces next to each other, which does according to string.IndexOf (even if i tell the string to replace all occurrences of two spaces next to each other). After some testing it seems \xAD is somehow causing this issue.

public class ReplaceIndexOfSymmetryTest
{
    [Test]
    public void IndexOfShouldNotFindReplacedString()
    {
        string testText = "\x61\x20\xAD\x20\x62";
        const string TWO_SPACES = "  ";
        const string ONE_SPACE = " ";
        string result = testText.Replace(TWO_SPACES, ONE_SPACE);
        Assert.IsTrue(result.IndexOf(TWO_SPACES) < 0);
    }
}
like image 444
ZFE Avatar asked Feb 07 '11 15:02

ZFE


2 Answers

Yes, I've come across the same thing before (although with different characters). Basically IndexOf will take various aspects of "special" Unicode characters into account when finding matches, whereas Replace just treats the strings as a sequence of code points.

From the IndexOf docs:

This method performs a word (case-sensitive and culture-sensitive) search using the current culture. The search begins at the first character position of this instance and continues until the last character position.

... and from Replace:

This method performs an ordinal (case-sensitive and culture-insensitive) search to find oldValue.

You could use the overload of IndexOf which takes a StringComparison, and force it to perform an ordinal comparison though.

like image 163
Jon Skeet Avatar answered Oct 18 '22 16:10

Jon Skeet


Like Jon said, use StringComparison.Ordinal to get it right.

Assert.IsTrue(result.IndexOf(TWO_SPACES, StringComparison.Ordinal) < 0);
like image 35
mgronber Avatar answered Oct 18 '22 18:10

mgronber