1

I'm writing a small app using VS Express 2013 and C# for Windows Phone 8.1:

Using an AutoSuggestBox tool, I'd like the user's input compare with a List of strings, however the strings in list contain accented characters, like "č,š,ť" and I want to show the user even the results containing "č" when he types "c". How can I do that?

What I have:

var resultList = SuggestionsList.Where(s => s.Contains(suggestions.Text));
suggestions.ItemsSource = resultList;

Where "SuggestionsList" is the original list of strings and "suggestions" is the name of the autosuggestbox.

Thank you.

user2864740
  • 60,010
  • 15
  • 145
  • 220
majo dom
  • 33
  • 5
  • Thats a tough one, I would expect that you would have to reform suggestions.text with the accented variants and re-perform the search for each. – vesuvious Aug 05 '14 at 16:52
  • Would you like to find "đ" if "dj" (as in Djokovic) is entered? If yes then you may need to invent your own `Contains` function that reduces all suggestion words to not only their diacritic-free variants, but also accounts for special cases that have nothing to do with diacritics. – Dialecticus Aug 05 '14 at 16:59

2 Answers2

1

Use RegEx. So if your user is searching for "cat", you could look for something like "[cč]at". Only some of the English language letters have accented variants, so you could make a static list of those and easily construct a RegEx based on the input.

Another, technically more sound approach has been discussed in this post.

RegEx Example

Suppose your input string is "cat" and you want to search for all variants of the letter "c". As a first step you'll construct your RegEx using a simple loop:

string MyRegEx = "";
for(int i=0; i<input.Length; i++)
{
    switch(input[i])
    {
        case 'a':
            MyRegEx += [aâà];
            break;
        case 'c':
            MyRegEx += [cč];
            break;

        ....

        default: //for letters that do not have any accented variants
            MyRegEx += input[i];
            break;
    }
}

System.Text.RegularExpressions.RegEx R = new System.Text.RegularExpressions.RegEx(MyRegEx);
var Your Results = SuggestionsList.Where(s => R.IsMatch(s.ToLower()));
Community
  • 1
  • 1
dotNET
  • 33,414
  • 24
  • 162
  • 251
  • Thanks, the RegEX way actually could be a good one, however I'm totally new with C# or anything Windows whatsoever, could you show some little example or a website with an example of searching a list using REGEX? Thank you very much! – majo dom Aug 05 '14 at 17:13
  • Added a simple example with skeleton. You'll need to fill up all desired variants in the `switch` part. – dotNET Aug 05 '14 at 17:54
  • I just realize that now I can't make case insensitive search. Do I really have to add all letter + cases to the regex? edit: nevermind, added .ToLower() to input...sorry and thanks! – majo dom Aug 06 '14 at 17:21
  • @majodom: That's fine. You also have the `IgnoreCase` option available when you create the `RegEx` object. See RegEx constructor for more information. – dotNET Aug 06 '14 at 20:34
0

You would need to compare with a diactriticless version of the string, you can achieve that by using a feature in Unicode string libraries (available in C#) called normalization (String.Normalize). FormD normalization splits a compound character into "base character" and diactrics.

You can use this code snippet to strip a diacritic from a character using normalization:

string formDString = txt.Normalize(NormalizationForm.FormD);

var sb = new StringBuilder();

var len = formDString.Length;

for (int i = 0; i < len; i++)
{
    var formDChar = formDString[i];

    System.Globalization.UnicodeCategory category = System.Globalization.CharUnicodeInfo.GetUnicodeCategory(formDChar);

    if (category != System.Globalization.UnicodeCategory.NonSpacingMark)
    {
        sb.Append(formDChar);
    }
}
Tamim Al Manaseer
  • 3,554
  • 3
  • 24
  • 33
  • Thank you, but it looks like Windows Phone doesn't support text Normalization? There's no string.Normalize available for me, even when using System.Text... – majo dom Aug 05 '14 at 17:11
  • Check my code sample, you call normalize from a string instance. I wrote String.Normalize so you know that it's a string method – Tamim Al Manaseer Aug 05 '14 at 17:28