2014-10-27 242 views
-1

我正在努力正确映射网站上的链接。计算字符串模式的出现次数,使用Linq的字符串

我需要能够计算../在字符串中出现的频率。 在这一刻我有一个功能,循环的字符串和计数,而这个工程,即时通讯寻找Linq解决方案

我知道,我可以这样

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

单个字符计数,但,我可以通过使用LINQ,算上模式../出现的频率?这可能吗?

+3

为什么你要使用LINQ,这似乎是一个正则表达式的工作? – 2014-10-27 09:46:14

+3

我有一把锤子。我需要把这个螺丝钉插入墙上。我怎么用锤子打它? – 2014-10-27 09:46:15

+0

幸运的是,如果直接在字符串上使用LINQ,那么在IEnumerable 上使用LINQ时,不会使用LINQ,因为您可以真正离开LINQ是一个索引枚举。 我会看看http://stackoverflow.com/questions/541954/how-would-you-count-occurrences-of-a-string-within-a-string – tolanj 2014-10-27 09:49:20

回答

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或正则表达式的方法。

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

这显示了差异:

string str = "ottotto"; 
int count = str.ContainsCount("otto");  // 2 
count = str.ContainsCount("otto", false); // 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(); 
+0

当然'Href.Count(x => x.Contains(“../”));'更容易阅读? .. – 2014-10-27 09:47:27

+1

@SimonWhitehead;你凭什么呢?上面的LINQ似乎有缺陷,因为 .Contains(“string”)没有意义。 – 2014-10-27 09:49:05

+0

公平点。睡觉对我来说! – 2014-10-27 09:53:03

2

你可以做到这一点很好地与正则表达式

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

3 
0

正则表达式(见梅德Ledentsov的答案)是这里要好得多;然而LINQ的也是可能的:

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

    // 2 
    int result = source 
    .Where((item, index) => source.Substring(index).StartsWith(@"../")) 
    .Count(); 
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; 
} 

或者,使用一些字符串提供的方法:

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; 
} 

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

相关问题