在任何位置使用通配符按字符串过滤记录

Filter records by string using wildcard in any position

我想用 lambda 表达式过滤记录。条件是它是否包含给定的字符串,或者几乎相同的字符串只有一个字符不同。 几乎相同的意思:其中一个字符可以是任何字符,但只能是一个。

例如: 搜索字符串:'ABC' 那么条件必须是:'[any char]BC' or 'A[any char]C' or 'AB[any char]'

有谁知道有什么专业的解决办法吗? 提前致谢。

解决方案(感谢 LiamK):

         var count = s1.Zip(s2, (c1, c2) => c1 == c2 ? 0 : 1).Sum();

您要查找的指标称为两个字符串之间的 Levenshtein 距离。您可以创建此算法的实现,然后在您的 where 子句中使用它:

public IEnumerable<string> MyFunc(string searchString)
{
    return myThingToSearch.Where(x => LevenshteinDistance(x, searchString) <= 1);
}

public static int LevenshteinDistance(string s1, string s2)
{
    if (s1 == s2)
    {
        return 0;
    }

    if (s1.Length == 0)
    {
        return s2.Length;
    }

    if (s2.Length == 0)
    {
        return s1.Length;
    }

    int[] v0 = new int[s2.Length + 1];
    int[] v1 = new int[s2.Length + 1];
    for (int i = 0; i < v0.Length; i++)
    {
        v0[i] = i;
    }

    for (int i = 0; i < s1.Length; i++)
    {
        v1[0] = i + 1;

        for (int j = 0; j < s2.Length; j++)
        {
            var cost = (s1[i] == s2[j]) ? 0 : 1;
            v1[j + 1] = Math.Min(v1[j] + 1, Math.Min(v0[j + 1] + 1, v0[j] + cost));
        }

        for (int j = 0; j < v0.Length; j++)
        {
            v0[j] = v1[j];
        }
    }
    return v1[s2.Length];
}

旁注:Levenshtein 距离度量还将 'BC' 或 'ABCD' 之类的字符串与搜索字符串 'ABC' 匹配,因为这些字符串在技术上仅 'off-by-one' 来自搜索字符串。我不确定这在您的规范中是否可以接受。如果没有,请告诉我们。该问题是近似字符串匹配的一个子集,您可以使用 Hamming 距离代替