C# 检查字符串是否包含一个单词,然后检查它是否以该单词开头,如果不包含?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11107505/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 16:30:25  来源:igfitidea点击:

Checking If a String Contains a Word and Then Checking If It Starts With said Word and If It Doesnt?

c#.net

提问by

Having another tough one here guys, basically I would like to check if a string contains the word "Foo" and if it does contain it, does it start with it? If it does start with Foo, it should be the only Foo that starts with a capital, all others should be small letters.

这里有另一个棘手的问题,基本上我想检查一个字符串是否包含“Foo”这个词,如果它包含它,它是否以它开头?如果它确实以 Foo 开头,它应该是唯一以大写开头的 Foo,所有其他都应该是小写字母。

If the above criteria is met, it should return true.

如果满足上述条件,则应返回 true。

If the string contains Foo but doesn't start with Foo, it should immediately return false since you cant have a capital Foo in the middle of the string.

如果字符串包含 Foo 但不以 Foo 开头,则应立即返回 false,因为字符串中间不能有大写的 Foo。

In the event that said string contains foo, but doesn't start with Foo, all instances of foo should be lowercase. If this criteria is met, return true.

如果所述字符串包含 foo,但不以 Foo 开头,则 foo 的所有实例都应为小写。如果满足此条件,则返回 true。

I should mention i am looking for C# code, I tried and have not yet succeeded, but since I have only been programming for 2 weeks, I don't think this will be trouble for some of you season pro's.

我应该提到我正在寻找 C# 代码,我尝试过但还没有成功,但由于我只编程了 2 周,我认为这不会对你们中的一些专业人士造成麻烦。



This is what I have tried as requested, I thinks its faaar off but at least I tried.

这是我按照要求尝试过的,我认为它很糟糕,但至少我尝试过。

            if (Title.Contains("Foo") == true && Regex.IsMatch(Title, "^Foo") == true)
        {
            CheckAnd = true;
        }
        else if (Title.Contains("Foo") == true && Regex.IsMatch(Title, "^Foo") == false)
        {
            CheckAnd = false;
        }
        else if (Regex.IsMatch(Title, "^foo"))
        {
            CheckAnd = false;
        }
        else
        {
            CheckAnd = true;
        }


Ok guys, nearly there, this is what I got from all your answers:

好的,快到了,这就是我从你所有的答案中得到的:

if (Title.IndexOf("Foo") == 0 && Title.LastIndexOf("Foo") == 0)
        {
            CheckAnd = true;
        }
        else if (Title.LastIndexOf("Foo") > 0)
        {
            CheckAnd = false;
        }
        else if(Title.Contains("foo") && Title.StartsWith("Foo") == false && PUT CHECK HERE)

The last thing I need to check that all occurrences of foo are lowercase in the last else if statement ?

我需要检查最后一个 else if 语句中所有出现的 foo 都是小写的最后一件事?

采纳答案by Jason De Oliveira

If I undestood it correctly this should do it !

如果我正确理解它应该这样做!

    if (testString.IndexOf("Foo") == 0 && testString.LastIndexOf("Foo") == 0)
        // "Foo foo foo"
        return true;
    else if (testString.IndexOf("Foo") == 0 && testString.LastIndexOf("Foo") > 0)
        // "Foo foo Foo"
        return false;
    else if (testString.Contains("foo")  && testString.IndexOf("Foo") > 0)
        // "foo Foo foo" or "foo foo Foo"
        return false; 
    else if (testString.Contains("foo") && !testString.Contains("Foo"))
        // "foo foo foo"
        return true;  

回答by Thousand

this will return true(because it contains the word Foo), and then false(because Foo isnt at the start of the sentence).

这将返回true(因为它包含单词 Foo),然后false(因为 Foo 不在句子的开头)。

        string word = "I am a string i contain Foo, aint that nice?";
        bool conts = word.Contains("Foo");
        int pos = word.IndexOf("Foo");                 
        if (conts)
        {
            if (pos != 0)
            {
                // do something
            }

        }

回答by Forte L.

Please refer to String.IndexOf Method:

请参考 String.IndexOf 方法:

http://msdn.microsoft.com/en-us/library/k8b1470s.aspx

http://msdn.microsoft.com/en-us/library/k8b1470s.aspx

The search is case sensitive, so just look for the capitalized word (Ex: "Foo"). If IndexOf returns 0, then the word is at the first position.

搜索区分大小写,因此只需查找大写单词(例如:“Foo”)。如果 IndexOf 返回 0,则该词位于第一个位置。

Edit: This is how I would do it (after seeing your code)

编辑:这就是我要做的(在看到你的代码后)

//changed to check for lowercase foo
if ((Title.StartsWith("Foo") && Title.LastIndexOf("Foo") == 0) 
|| (Title.Contains("foo") && !Title.StartsWith("foo")))
{
    CheckAnd = true;
}
else
    CheckAnd = false;

回答by MAV

If I understand the problem correctly this method should work.

如果我正确理解了问题,则此方法应该有效。

    public bool ContainsFoo(string s)
    {
        bool result = true;

        if (s.IndexOf("Foo") > 0)
        {
            result = false;
        }
        else if (s.LastIndexOf("Foo") > 0)
        {
            result = false;
        }
        return result;
    }

Let me know if I misunderstood something.

如果我误解了什么,请告诉我。

回答by Erasmus

Don't want to read my book? Here's the answer:

不想看我的书?答案如下:

As a bonus, this is the fastest performing solution.

作为奖励,这是性能最快的解决方案。

public void CheckValidFoo(String Title) {     
    return (Title.LastIndexOf("Foo") <= 0);
}

Read on for a lessons in coding logic (humor this old man)

继续阅读编码逻辑课程(幽默这个老人)

This question may be old, but for the sake of those finding this question laterwho are curiousabout how to logically distill word problems(so please don't downvote this lurker who finally decided to post), here's my massively overdone analysis for this extremely simple homework assignment:

这个问题可能很旧,但是为了那些后来发现这个问题的人对如何从逻辑上提取单词问题感到好奇(所以请不要贬低这个最终决定发帖的潜伏者),这是我对这个极其过度的分析简单的家庭作业:

I ran a set of tests to see what options were the fastest - this often helps me see flaws in my logic. I am also going to explain my thought process, since, IMHO, understanding how to distill a problem to it's core logic is a good thing to know for real world use.

我运行了一组测试来查看哪些选项是最快的——这通常有助于我发现逻辑中的缺陷。我还将解释我的思考过程,因为,恕我直言,了解如何将问题提炼为其核心逻辑对于现实世界的使用来说是一件好事。

After all, that's what Business Requirements Docs are... word problems that need to be distilled into functional specs (e.g. architectural design).

毕竟,这就是业务需求文档……需要提炼成功能规范(例如架构设计)的文字问题。

Step 1

第1步

Eliminate Extraneous Information
Based on the requirements given, lower case foo may or may not matter: There is no explicit statement that a string not containing foo and not containing Foo should return false; There is also no explicit statement that says a string not containing Foo and not containing foo should return true.

消除无关信息
根据给定的要求,小写 foo 可能重要也可能无关紧要:没有明确声明不包含 foo 且不包含 Foo 的字符串应该返回 false;也没有明确的声明说不包含 Foo 且不包含 foo 的字符串应该返回 true。

In a perfect world, you would go back for clarification on the requirements, but in some cases, there isn't time. Assuming there is a deadline, I would move forward with the assumption that all we care about is Foo being uppercase only when in the first position in the sentence, lower case at all other times, so we will ignore foo altogether, and if the "client" complains, point out the missing clarity and explain why you made a judgement call (to keep the project on time, and on budget, if applicable).

在一个完美的世界中,您会回去澄清要求,但在某些情况下,没有时间。假设有一个截止日期,我会继续假设我们只关心 Foo 仅在句子的第一个位置时是大写的,其他时候都是小写的,所以我们将完全忽略 foo,如果“客户”抱怨,指出缺少的清晰度并解释您为什么做出判断(以保持项目按时并按预算进行,如果适用)。

Step 2

第2步

Break down the logic into OR/AND pieces:
Breaking Foo into components lets us look at individual pieces, which can be easier than looking at the whole. So, if we break the string into "stuff before Foo" (even if that is "nothing") and "stuff after Foo" OR if Foo isn't there to break up the string, we only have one piece to look at. (Our brains do this all the time - it's called pattern recognition).

将逻辑分解为 OR/AND 部分:将
Foo 分解为组件让我们可以查看单个部分,这比查看整体更容易。因此,如果我们将字符串拆分为“Foo 之前的东西”(即使那是“什么都没有”)和“Foo 之后的东西”,或者如果 Foo 不在那里拆分字符串,那么我们只需要查看一个片段。(我们的大脑一直都在这样做——这叫做模式识别)。

IF The string cannot be split because Foo is not found
    OR
      splitting on Foo gives us no more than two pieces: nothing before, and everything after
       AND(implied by the previous check only finding an empty "before" and only one "section" in the "after")       Foo is not found anywhere else in the string

如果字符串不能被分割,因为foo是没有发现
    或
      在富拆分为我们提供了不超过两件:之前什么都没有,一切之后
       AND(由先前的检查只发现一个空的暗示“之前”和只有一个“节” “之后”)       在字符串中的其他任何地方都找不到 Foo

Sound good? Well, it's 100% accurate, but we can cut some cruft and distill it further - keep in mind computers don't think like humans, so our mental processing is inefficient for them.

听起来不错?嗯,它是 100% 准确的,但是我们可以减少一些细节并进一步提炼它 - 请记住,计算机不像人类那样思考,因此我们的心理处理对它们来说效率低下。

Because Foo not being found at all is considered valid, and Foo at the beginning is valid, but Foo anywhere else later in the string is invalid, we can say:

因为根本没有找到 Foo 被认为是有效的,并且开头的 Foo 是有效的,但字符串中其他任何地方的 Foo 都是无效的,我们可以说:

IF Foo is not found
    OR
      Foo is not found anywhere in the string past the first position

IF Foo is not found
    OR
      Foo 未在字符串中第一个位置之后的任何位置找到

Seems tight, right? Don't stop now. We can do better.

看起来很紧对吧?现在不要停下来。我们可以做得更好。

If Foo is found at the beginning, we're fine with it, right? So "Foo is not Found" OR "Foo is found at the beginning AND Foo is not found anywhere else" can be looked at from a more pure logic (boolean, true/false, black and white) perspective:

如果一开始就找到了 Foo ,那我们就没事了,对吧?因此,可以从更纯逻辑(布尔值、真/假、黑白)的角度来看“未找到 Foo”或“在开头找到 Foo 且在其他任何地方都找不到 Foo”:

  • LET FNA = "Foo is not found anywhere"
  • LET FN1 = "Foo is not found in position 1"
  • LET FN2 = "Foo is not found after position 1"
  • LET FF1 = "Foo is found in position 1"
  • LET FF2 = "Foo is found after position 1"
  • LET FNA = "在任何地方都找不到 Foo"
  • LET FN1 = "在位置 1 中找不到 Foo"
  • LET FN2 = "在位置 1 之后找不到 Foo"
  • LET FF1 = "Foo 位于位置 1"
  • LET FF2 = "在位置 1 之后找到 Foo"

So now define as invalid only those cases which are guaranteed invalid, and mark the rest as valid. We'll use boolean math to determine all use cases.

因此,现在仅将那些保证无效的情况定义为无效,并将其余情况标记为有效。我们将使用布尔数学来确定所有用例。

  • LET FNA = valid
  • LET FN1 = valid
  • LET FN2 = valid
  • LET FF1 = valid
  • LET FF2 = invalid
  • 让 FNA = 有效
  • 让 FN1 = 有效
  • 让 FN2 = 有效
  • 让 FF1 = 有效
  • 让 FF2 = 无效

Now that we've labeled only the cases that absolutely force a return of false, we can do the math to see the only cases where we get an invalid/false value.

现在我们只标记了绝对强制返回 false 的情况,我们可以进行数学计算以查看我们获得无效/错误值的唯一情况。

FNA = FN1 and FN2 (so if FNA & X = true, then F1 & X must be true, and F2 & X must also be true);

FNA = FN1 和 FN2(所以如果 FNA & X = 真,则 F1 & X 必须为真,F2 & X 也必须为真);

FNA and/or FF1 = true, so we know that all combinations of and/or of these 4 variables = true; This leaves only one variable left to combine, and we can see really quickly that FF2 and anything will always be false.

FNA 和/或 FF1 = 真,所以我们知道这 4 个变量和/或的所有组合 = 真;这样只剩下一个变量可以组合,我们可以很快看到 FF2 和任何东西总是假的。

So translated back into human logic... see how much simpler this task is?

所以转换回人类逻辑......看看这个任务有多简单?

ONLY FALSE IFFoo is found after position 1

如果在位置 1 之后找到 Foo 则为FALSE

Or, to flip the boolean (since the requirements say to return true for valid cases):

或者,翻转布尔值(因为要求说在有效情况下返回 true):

IF Foo is NOT found after position 1, string is valid.

如果在位置 1 后未找到 Foo,则字符串有效。

Or, to put it more like a computer's thinking:

或者,更像是计算机的思维:

IF scanning from the endof the string until the 2nd to the last character does not find Foo, string is valid

如果从字符串末尾扫描到第2个到最后一个字符没有找到Foo,则字符串有效

There, now we can't distill it any further down. So let's code these different bits of logic and see how they perform in real code:

在那里,现在我们不能再进一步提炼它了。因此,让我们编写这些不同的逻辑位,看看它们在实际代码中的表现:

using System;

public static class Test
{
public static bool CheckFooTestA(String SearchMe, String[] FindMe)
{
    //split the string like the human eye does and check the count of Foos 
    //and the position of the Foo or Foos to determine our logic:
    string[] v = SearchMe.Split(FindMe, StringSplitOptions.None);

         //Foo not found, OR foo found once and was at the beginning of the string
    return (v.Length == 0 || v.Length == 1 && v[0] == String.Empty);
}
public static bool CheckFooTestB(String SearchMe, String[] FindMe)
{
    //scan the way computers or non-speed readers do, and look for the first instance of Foo
    int i = SearchMe.IndexOf(FindMe[0]);

    //Foo not found OR 
    //    foo found at the start of the string 
    //    AND the last Foo found is also at the start of the string
    return (i == -1 || i == 0 && SearchMe.LastIndexOf(FindMe[0]) == 0 );
}
public static bool CheckFooTestC(String SearchMe, String[] FindMe)
{
    //Use the logic we distilled from the word problem to make this single check:
    return (SearchMe.LastIndexOf(FindMe[0]) <= 0);
}
public static void Main()
{
    String[] x = new String[]{
        "Foo foo Foo bar",
        "Foo foo foo bar",
        "foo foo Foo bar",
        "foo foo foo bar",
        "asfda asdfa asf" };

    var s = new []{"Foo"};
    var i = 0;
    bool f=false;
    long End = DateTime.Now.Ticks;
    long Start = DateTime.Now.Ticks;
    for (; i < 1000; i++) {
        f = CheckFooTestA(x[i%5],s);
    }
    End = DateTime.Now.Ticks;
    Console.WriteLine((End - Start).ToString() + " ticks (Test A)");

    i = 0;
    f = false;
    End = DateTime.Now.Ticks;
    Start = DateTime.Now.Ticks;
    for (; i < 1000; i++) {
        f = CheckFooTestB(x[i%5],s);
    }
    End = DateTime.Now.Ticks;
    Console.WriteLine((End - Start).ToString() + " ticks (Test B)");

    i = 0;
    f = false;
    End = DateTime.Now.Ticks;
    Start = DateTime.Now.Ticks;
    for (; i < 1000; i++) {
        f = CheckFooTestC(x[i%5],s);
    }
    End = DateTime.Now.Ticks;
    Console.WriteLine((End - Start).ToString() + " ticks (Test C)");
}
}
Test.Main();

Output:

输出:

260510 ticks (Test A)
117150 ticks (Test B)
76160 ticks (Test C)

Results and Conclusions

结果和结论

Test A (human logic of visually splitting on/counting the words found), compared to test B (scanning using indexes with the distilled logic), Test A runs over 220% longer!

测试 A(对找到的单词进行视觉拆分/计数的人类逻辑),与测试 B(使用带有提取逻辑的索引进行扫描)相比,测试 A 的运行时间长了 220% 以上!

Test C is the best performer - only one scan of the string needed. Coming in at less than 30% the processing time required (Test A takes over 340%! of the amount of time Test C requires to complete the same work).

测试 C 是最好的执行者 - 只需要对字符串进行一次扫描。进入所需的处理时间不到 30%(测试 A 占用了测试 C 完成相同工作所需时间的 340%!)。

So hopefully some student somewhere has read this and the lightbulb goes on. You can always come up with ways to make stuff that "works", but understanding boolean logic and how to distill a concept down to it's core can make a significant impact on the quality of your work.

所以希望某个地方的某个学生已经读过这篇文章,并且灯泡继续亮着。你总是可以想出一些方法来制作“有效”的东西,但是理解布尔逻辑以及如何将一个概念提炼到它的核心可以对你的工作质量产生重大影响。

Happy coding, everyone!

祝大家编码愉快!