C# - 从另一个字符串中删除第一次出现的子字符串的最简单方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2201595/
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-07 00:21:00  来源:igfitidea点击:

C# - Simplest way to remove first occurrence of a substring from another string

c#string

提问by Vaccano

I need to remove the first (and ONLY the first) occurrence of a string from another string.

我需要从另一个字符串中删除第一个(并且仅第一个)出现的字符串。

Here is an example replacing the string "\\Iteration". This:

这是一个替换字符串的示例"\\Iteration"。这个:

ProjectName\Iteration\Release1\Iteration1

would become this:

会变成这样:

ProjectName\Release1\Iteration1

Here some code that does this:

这里有一些代码可以做到这一点:

const string removeString = "\Iteration";
int index = sourceString.IndexOf(removeString);
int length = removeString.Length;
String startOfString = sourceString.Substring(0, index);
String endOfString = sourceString.Substring(index + length);
String cleanPath = startOfString + endOfString;

That seems like a lot of code.

这似乎是很多代码。

So my question is this: Is there a cleaner/more readable/more concise way to do this?

所以我的问题是:有没有更干净/更易读/更简洁的方法来做到这一点?

采纳答案by LukeH

int index = sourceString.IndexOf(removeString);
string cleanPath = (index < 0)
    ? sourceString
    : sourceString.Remove(index, removeString.Length);

回答by Joel Etherton

string myString = sourceString.Remove(sourceString.IndexOf(removeString),removeString.Length);

EDIT: @OregonGhost is right. I myself would break the script up with conditionals to check for such an occurence, but I was operating under the assumption that the strings were given to belong to each other by some requirement. It is possible that business-required exception handling rules are expected to catch this possibility. I myself would use a couple of extra lines to perform conditional checks and also to make it a little more readable for junior developers who may not take the time to read it thoroughly enough.

编辑:@OregonGhost 是对的。我自己会用条件分解脚本来检查这种情况,但我是在假设字符串是根据某些要求而属于彼此的假设下进行操作的。业务所需的异常处理规则可能会捕捉到这种可能性。我自己会使用几行额外的行来执行条件检查,并使其对于可能没有花时间仔细阅读它的初级开发人员更具可读性。

回答by CaffGeek

Wrote a quick TDD Test for this

为此编写了一个快速的 TDD 测试

    [TestMethod]
    public void Test()
    {
        var input = @"ProjectName\Iteration\Release1\Iteration1";
        var pattern = @"\Iteration";

        var rgx = new Regex(pattern);
        var result = rgx.Replace(input, "", 1);

        Assert.IsTrue(result.Equals(@"ProjectName\Release1\Iteration1"));
    }

rgx.Replace(input, "", 1); says to look in input for anything matching the pattern, with "", 1 time.

rgx.Replace(输入, "", 1); 说要在输入中查找与模式匹配的任何内容,用“”,1 次。

回答by Mike Valenty

You could use an extension methodfor fun. Typically I don't recommend attaching extension methods to such a general purpose class like string, but like I said this is fun. I borrowed @Luke's answer since there is no point in re-inventing the wheel.

您可以使用扩展方法来获得乐趣。通常我不建议将扩展方法附加到像字符串这样的通用类,但就像我说的那样,这很有趣。我借用了@Luke 的回答,因为重新发明轮子没有意义。

[Test]
public void Should_remove_first_occurrance_of_string() {

    var source = "ProjectName\Iteration\Release1\Iteration1";

    Assert.That(
        source.RemoveFirst("\Iteration"),
        Is.EqualTo("ProjectName\Release1\Iteration1"));
}

public static class StringExtensions {
    public static string RemoveFirst(this string source, string remove) {
        int index = source.IndexOf(remove);
        return (index < 0)
            ? source
            : source.Remove(index, remove.Length);
    }
}

回答by Greg Roberts

I definitely agree that this is perfect for an extension method, but I think it can be improved a bit.

我绝对同意这对于扩展方法来说是完美的,但我认为它可以改进一点。

public static string Remove(this string source, string remove,  int firstN)
    {
        if(firstN <= 0 || string.IsNullOrEmpty(source) || string.IsNullOrEmpty(remove))
        {
            return source;
        }
        int index = source.IndexOf(remove);
        return index < 0 ? source : source.Remove(index, remove.Length).Remove(remove, --firstN);
    }

This does a bit of recursion which is always fun.

这做了一些递归,这总是很有趣。

Here is a simple unit test as well:

这里还有一个简单的单元测试:

   [TestMethod()]
    public void RemoveTwiceTest()
    {
        string source = "look up look up look it up";
        string remove = "look";
        int firstN = 2;
        string expected = " up  up look it up";
        string actual;
        actual = source.Remove(remove, firstN);
        Assert.AreEqual(expected, actual);

    }

回答by malcolm waldron

sourceString.Replace(removeString, "");

回答by Daniel Filipe

If you'd like a simple method to resolve this problem. (Can be used as an extension)

如果你想要一个简单的方法来解决这个问题。(可作为扩展使用)

See below:

见下文:

    public static string RemoveFirstInstanceOfString(this string value, string removeString)
    {
        int index = value.IndexOf(removeString, StringComparison.Ordinal);
        return index < 0 ? value : value.Remove(index, removeString.Length);
    }

Usage:

用法:

    string valueWithPipes = "| 1 | 2 | 3";
    string valueWithoutFirstpipe = valueWithPipes.RemoveFirstInstanceOfString("|");
    //Output, valueWithoutFirstpipe = " 1 | 2 | 3";

Inspired by and modified @LukeH's and @Mike's answer.

受到@LukeH 和@Mike 的回答的启发和修改。

Don't forget the StringComparison.Ordinal to prevent issues with Culture settings. https://www.jetbrains.com/help/resharper/2018.2/StringIndexOfIsCultureSpecific.1.html

不要忘记 StringComparison.Ordinal 以防止文化设置出现问题。 https://www.jetbrains.com/help/resharper/2018.2/StringIndexOfIsCultureSpecific.1.html