我正在做一些事情,我意识到我想要在一个字符串中找到多少个/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;

当前回答

            var conditionalStatement = conditionSetting.Value;

            //order of replace matters, remove == before =, incase of ===
            conditionalStatement = conditionalStatement.Replace("==", "~").Replace("!=", "~").Replace('=', '~').Replace('!', '~').Replace('>', '~').Replace('<', '~').Replace(">=", "~").Replace("<=", "~");

            var listOfValidConditions = new List<string>() { "!=", "==", ">", "<", ">=", "<=" };

            if (conditionalStatement.Count(x => x == '~') != 1)
            {
                result.InvalidFieldList.Add(new KeyFieldData(batch.DECurrentField, "The IsDoubleKeyCondition does not contain a supported conditional statement. Contact System Administrator."));
                result.Status = ValidatorStatus.Fail;
                return result;
            }

需要做一些类似于从字符串测试条件语句的事情。

用单个字符替换我正在寻找的内容,并计算单个字符的实例数。

显然,在发生这种情况之前,您需要检查您正在使用的单个字符是否存在于字符串中,以避免错误计数。

其他回答

Split (may)胜过IndexOf(用于字符串)。

上面的基准测试似乎表明Richard Watson是最快的字符串,这是错误的(可能差异来自我们的测试数据,但由于下面的原因,它看起来很奇怪)。

如果我们更深入地研究这些方法在.NET中的实现(对于Luke H, Richard Watson方法),

IndexOf取决于区域性,它将尝试检索/创建ReadOnlySpan,检查是否必须忽略大小写等。最后执行不安全/本机调用。 Split能够处理多个分隔符,并有一些StringSplitOptions 并且必须创建字符串[]数组并用分割结果填充它(所以做一些子字符串)。根据字符串出现的数量,Split可能比IndexOf更快。

顺便说一下,我做了一个简化版本的IndexOf(它可以更快,如果我使用指针和不安全,但不勾选应该是ok的大多数),它至少快了4个数量级。

基准测试(来源GitHub)

通过搜索一个常见的单词(the)或一个小句子 莎士比亚,理查三世。

Method Mean Error StdDev Ratio
Richard_LongInLong 67.721 us 1.0278 us 0.9614 us 1.00
Luke_LongInLong 1.960 us 0.0381 us 0.0637 us 0.03
Fab_LongInLong 1.198 us 0.0160 us 0.0142 us 0.02
-------------------- -----------: ----------: ----------: ------:
Richard_ShortInLong 104.771 us 2.8117 us 7.9304 us 1.00
Luke_ShortInLong 2.971 us 0.0594 us 0.0813 us 0.03
Fab_ShortInLong 2.206 us 0.0419 us 0.0411 us 0.02
--------------------- ----------: ---------: ---------: ------:
Richard_ShortInShort 115.53 ns 1.359 ns 1.135 ns 1.00
Luke_ShortInShort 52.46 ns 0.970 ns 0.908 ns 0.45
Fab_ShortInShort 28.47 ns 0.552 ns 0.542 ns 0.25
public int GetOccurrences(string input, string needle)
{
    int count = 0;
    unchecked
    {
        if (string.IsNullOrEmpty(input) || string.IsNullOrEmpty(needle))
        {
            return 0;
        }

        for (var i = 0; i < input.Length - needle.Length + 1; i++)
        {
            var c = input[i];
            if (c == needle[0])
            {
                for (var index = 0; index < needle.Length; index++)
                {
                    c = input[i + index];
                    var n = needle[index];

                    if (c != n)
                    {
                        break;
                    }
                    else if (index == needle.Length - 1)
                    {
                        count++;
                    }
                }
            }
        }
    }

    return count;
}
string s = "HOWLYH THIS ACTUALLY WORKSH WOWH";
int count = 0;
for (int i = 0; i < s.Length; i++)
   if (s[i] == 'H') count++;

它只是检查字符串中的每个字符,如果该字符是您正在搜索的字符,则添加一个来计数。

string source = "/once/upon/a/time/";
int count = 0, n = 0;
while ((n = source.IndexOf('/', n) + 1) != 0) count++;

这是Richard Watson的答案的一个变体,char在字符串中出现的次数越多,效率就会提高一点,代码也会更少!

虽然我必须说,在没有广泛测试每个场景的情况下,我确实看到了使用以下方法的显著速度提升:

int count = 0;
for (int n = 0; n < source.Length; n++) if (source[n] == '/') count++;

字符串中的字符串:

在“..”中找到“etc”。JD JD JD JD等等。JDJDJDJDJDJDJDJD等等。”

var strOrigin = " .. JD JD JD JD etc. and etc. JDJDJDJDJDJDJDJD and etc.";
var searchStr = "etc";
int count = (strOrigin.Length - strOrigin.Replace(searchStr, "").Length)/searchStr.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