使用Linq计算字符串模式的出现次数

时间:2014-10-27 09:42:39

标签: c# string linq

我正在努力正确地映射网站上的链接。

我需要能够计算字符串中出现../的频率。 此时我有一个循环遍历字符串的函数并计数,而这是有效的,我正在寻找Linq解决方案

我知道我可以算一个像这样的单个角色

 int count = Href.Count(f => f == '/');

但是,我可以使用LINQ计算模式../发生的频率吗?这可能吗?

5 个答案:

答案 0 :(得分:2)

你可以很好地使用Regex

var dotdotslash=new Regex(@"\.\./");
string test="../../bla/../";
int count=dotdotslash.Matches(test).Count;

3

答案 1 :(得分:1)

是的,这是可能的,但它很尴尬,它会很慢,而且很难阅读。不要使用它。

How would you count occurrences of a string within a string?

src.Select((c, i) => src.Substring(i)).Count(sub => sub.StartsWith(target))

或者,这看起来很漂亮:

public static class StringExtensions
{
    public static IEnumerable<int> IndexOfAll(this string input, string value){
        var currentIndex = 0;

        while((currentIndex = input.IndexOf(value, currentIndex)) != -1)
            yield return currentIndex++;
    }
}

和用法:

"TESTHATEST"
    .IndexOfAll("TEST")
    .Count()
    .Dump();

答案 2 :(得分:1)

您可以使用此扩展方法:

public static int ContainsCount(this string input, string subString, bool countIntersecting = true, StringComparison comparison = StringComparison.CurrentCulture)
{
    int occurences = 0;
    int step = countIntersecting ? 1 : subString.Length;
    int index = -step;
    while ((index = input.IndexOf(subString, index + step, comparison)) >= 0)
        occurences++;
    return occurences;
}

使用纯字符串方法返回给定字符串中的子字符串数:

int count = Href.ContainsCount("../");

String-methods优于其他在效率方面使用LINQ或regex的方法。

此方法支持计算相交的子字符串(默认)和非重叠的子字符串。

这显示了不同之处:

string str = "ottotto";
int count = str.ContainsCount("otto");      // 2
count = str.ContainsCount("otto", false);   // 1

答案 3 :(得分:0)

正则表达式(参见 Dmitry Ledentsov的回答)在这里要好得多;但Linq也是可能的:

  String source = @"abc../def../";

  // 2
  int result = source
    .Where((item, index) => source.Substring(index).StartsWith(@"../"))
    .Count();

答案 4 :(得分:0)

实际上,你可以用真正的LINQy(和笨拙的:))这样的方式来做:

private static int CountPatternAppearancesInString(string str, string pattern)
{
    var count = str
        .Select(
            (_, index) =>
                index < str.Length - pattern.Length + 1 &&
                str.Skip(index)
                    .Take(pattern.Length)
                    .Zip(pattern, (strChar, patternChar) => strChar == patternChar)
                    .All(areEqual => areEqual))
        .Count(isMatch => isMatch);

    return count;
}

或者,使用一些String提供的方法:

private static int CountPatternAppearancesInString(string str, string pattern)
{
    var count = str
        .Select(
            (_, index) =>
                index < str.Length - pattern.Length + 1 &&
                str.IndexOf(pattern, index, pattern.Length) >= 0)
        .Count(isMatch => isMatch);

    return count;
}

但是,正如已经说过的那样,它不是最理想的,仅用于说明目的。