使用C#在数组中进行松散字符串搜索

时间:2012-04-06 09:22:21

标签: c# search word

我们说有一个

string[] array = {"telekinesis", "laureate", "Allequalsfive", "Indulgence"};

我们需要在这个数组中找到一个单词

通常我们会做以下事情:(或使用任何类似的方法来查找字符串)

bool result = array.Contains("laureate"); // returns true

就我而言,我正在搜索的单词可能有错误(如标题所示)。

例如,我无法区分字母“I”(大“i”)和“l”(小“L”)和“1”(第一)之间的区别。

有什么方法可以找到像“Allequalsfive”或“A11equalsfive”或“AIIequalsfive”这样的单词吗? (松散搜索)通常结果将是“假”。

如果我只能指定忽略一些字母..(序列是常量,其他字母是常量)。

3 个答案:

答案 0 :(得分:2)

您可以使用Contains的{​​{1}}重载。

实施你自己的平等比较器,忽略你想要的字母,然后离开。

答案 1 :(得分:2)

借助扩展方法& Levenshtein Distance算法

var array = new string[]{ "telekinesis", "laureate", 
                          "Allequalsfive", "Indulgence" };

bool b = array.LooseContains("A11equalsfive", 2); //returns true

-

public static class UsefulExtensions
{
    public static bool LooseContains(this IEnumerable<string> list, string word,int distance)
    {
        foreach (var s in list)
            if (s.LevenshteinDistance(word) <= distance) return true;
        return false;
    }

    //
    //http://www.merriampark.com/ldcsharp.htm
    //
    public static int LevenshteinDistance(this string s, string t)
    {
        int n = s.Length;
        int m = t.Length;
        int[,] d = new int[n + 1, m + 1];

        // Step 1
        if (n == 0)
            return m;

        if (m == 0)
            return n;

        // Step 2
        for (int i = 0; i <= n; d[i, 0] = i++){}

        for (int j = 0; j <= m; d[0, j] = j++){}

        // Step 3
        for (int i = 1; i <= n; i++)
        {
            //Step 4
            for (int j = 1; j <= m; j++)
            {
                // Step 5
                int cost = (char.ToUpperInvariant(t[j - 1]) == char.ToUpperInvariant(s[i - 1])) ? 0 : 1;

                // Step 6
                d[i, j] = Math.Min(
                    Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
                    d[i - 1, j - 1] + cost);
            }
        }
        // Step 7
        return d[n, m];
    }
}

答案 2 :(得分:1)

如果您只需要知道数组中是否包含松散的单词,那么您可以在搜索字和数组中“清理”要忽略的字母(例如,将“1”替换为“l”) :

Func<string, string> clean = x => x.ToLower().Replace('1', 'l');
var array = (new string[] { "telekinesis", "laureate", "A11equalsfive", "Indulgence" }).Select(x => clean(x));          
bool result = array.Contains(clean("allequalsfive"));

否则,您可以查找Where()LINQ关键字,该关键字允许您根据指定的函数过滤数组。