我正在做一些事情,我意识到我想要在一个字符串中找到多少个/s,然后我突然想到,有几种方法可以做到这一点,但不能决定哪种是最好的(或最简单的)。
目前我想说的是:
string source = "/once/upon/a/time/";
int count = source.Length - source.Replace("/", "").Length;
但我一点都不喜欢,有人愿意吗?
我并不想为此挖掘出正则表达式,对吧?
我知道我的字符串将包含我要搜索的项,所以你可以假设…
当然对于长度为> 1的字符串,
string haystack = "/once/upon/a/time";
string needle = "/";
int needleCount = ( haystack.Length - haystack.Replace(needle,"").Length ) / needle.Length;
从。net 7开始,我们就有了不需要分配(并且高度优化)的Regex api。计数尤其容易和有效。
var input = "abcd abcabc ababc";
var result = Regex.Count(input: input, pattern: "abc"); // 4
当匹配动态模式时,记得转义它们:
public static int CountOccurences(string input, string pattern)
{
pattern = Regex.Escape(pattern); // Aww, no way to avoid heap allocations here
var result = Regex.Count(input: input, pattern: pattern);
return result;
}
而且,作为固定模式的额外奖励,. net 7引入了分析器,帮助将正则表达式字符串转换为源代码生成的代码。这不仅避免了regex的运行时编译开销,而且还提供了非常可读的代码,展示了它是如何实现的。事实上,该代码通常至少与手动编写的任何替代代码一样有效。
如果您的正则表达式调用是合格的,分析程序将给出提示。简单地选择“转换为'GeneratedRegexAttribute '”并享受结果:
[GeneratedRegex("abc")]
private static partial Regex MyRegex(); // Go To Definition to see the generated code
如果你使用的是。net 3.5,你可以用LINQ在一行代码中完成:
int count = source.Count(f => f == '/');
如果你不想使用LINQ,你可以用:
int count = source.Split('/').Length - 1;
您可能会惊讶地发现,您原来的技术似乎比这两种方法都快30% !我刚刚用“/once/upon/a/time/”做了一个快速的基准测试,结果如下:
你的原稿= 12s
源。计数= 19秒
源。分裂= 17秒
Foreach(来自bobwienholt的答案)= 10s
(迭代次数为50,000,000次,因此在现实世界中您不太可能注意到太多差异。)
对于任何想要使用String扩展方法的人,
以下是我使用的基于张贴的最好的答案:
public static class StringExtension
{
/// <summary> Returns the number of occurences of a string within a string, optional comparison allows case and culture control. </summary>
public static int Occurrences(this System.String input, string value, StringComparison stringComparisonType = StringComparison.Ordinal)
{
if (String.IsNullOrEmpty(value)) return 0;
int count = 0;
int position = 0;
while ((position = input.IndexOf(value, position, stringComparisonType)) != -1)
{
position += value.Length;
count += 1;
}
return count;
}
/// <summary> Returns the number of occurences of a single character within a string. </summary>
public static int Occurrences(this System.String input, char value)
{
int count = 0;
foreach (char c in input) if (c == value) count += 1;
return count;
}
}