'Why are some characters ignored when calling LastIndexOf?

Please take a look at these codes :

string str_to_find = "➖➖➖➖➖➖➖➖➖➖\r\n";
string str = "Nancy" + str_to_find;
if (str.EndsWith(str_to_find)) {
    str = Remove_Last_String(str, str_to_find);
}

And here is the method :

public static string Remove_Last_String(string Source, string Find) {
    int i = Source.LastIndexOf(Find);
    if (i >= 0) {
        string new_str = Source.Substring(0, i);
        return new_str;
    }
    else return Source;
}

I want Nancy for the output.
But method returns :
Nancy➖➖➖➖➖➖➖➖➖➖
What is the problem about those strange characters & How can i fix it?



Solution 1:[1]

You are messing with unusual Unicode characters. Or maybe they are messing with you. Please always specify string comparison style. Use this in your code:

int i = Source.LastIndexOf(Find, StringComparison.Ordinal);

The StringComparison.Ordinal forces the comparison of strings to ignore current culture settings. Apparently, the culture settings make the algorithm to behave differently than you/we want/expect.

Solution 2:[2]

The docs state:

Character sets include ignorable characters, which are characters that are not considered when performing a linguistic or culture-sensitive comparison. In a culture-sensitive search, if value contains an ignorable character, the result is equivalent to searching with that character removed.

? is an ignorable character, which explains why searching for "\r\n" or "y??????????\r\n" behaves 'as expected', while "??????????\r\n" does not.

Using StringComparison.Ordinal, as shown by @AlKepp, will solve the issue since then the comparison is not culture sensitive.

See also List of ignorable characters for string comparison.

Solution 3:[3]

using System;
                    
public class Program
{
    public static void Main()
    {
        string str_to_find = "??????????\r\n";
        string str = "Nancy" + str_to_find;
        if (str.EndsWith(str_to_find)) {
            str = Remove_Last_String(str, str_to_find);
            Console.WriteLine(str);
        }
    }
    
    public static string Remove_Last_String(string Source, string Find) {


        int i = Find.Length;
        int j = Source.Length;
        if (i >= 0) {
            string new_str = Source.Substring(0, j-i);
            return new_str;
        }
        else return Source;
    }
}

it works, good luck

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Al Kepp
Solution 2 Wai Ha Lee
Solution 3