我需要从另一个字符串中删除第一个(并且只是第一个)字符串。
以下是替换字符串"\\Iteration"
的示例。这样:
ProjectName\\Iteration\\Release1\\Iteration1
会变成这样:
ProjectName\\Release1\\Iteration1
这里有一些代码可以做到这一点:
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;
这似乎是很多代码。
所以我的问题是:是否有更清晰/更可读/更简洁的方法来做到这一点?
答案 0 :(得分:125)
int index = sourceString.IndexOf(removeString);
string cleanPath = (index < 0)
? sourceString
: sourceString.Remove(index, removeString.Length);
答案 1 :(得分:24)
string myString = sourceString.Remove(sourceString.IndexOf(removeString),removeString.Length);
编辑:@OregonGhost是对的。我自己会用条件来破坏脚本来检查这种情况,但是我假设字符串被某些要求赋予了彼此属性。预计业务所需的异常处理规则可能会捕获这种可能性。我本人会使用一些额外的行来执行条件检查,并且对于那些可能没有花时间仔细阅读它的初级开发人员来说,它会更具可读性。
答案 2 :(得分:14)
sourceString.Replace(removeString, "");
答案 3 :(得分:10)
为此编写快速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);说要查看任何与模式相匹配的输入,用“”,1次。
答案 4 :(得分:6)
您可以使用扩展方法来获得乐趣。通常我不建议将扩展方法附加到像字符串这样的通用类,但就像我说这很有趣。我借用了@ 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);
}
}
答案 5 :(得分:2)
我绝对同意这对于扩展方法是完美的,但我认为它可以稍微改进一下。
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);
}
这会带来一些总是很有趣的递归。
这是一个简单的单元测试:
[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);
}
答案 6 :(得分:0)
如果您想使用一种简单的方法来解决此问题。 (可用作扩展名)
请参见下文:
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);
}
用法:
string valueWithPipes = "| 1 | 2 | 3";
string valueWithoutFirstpipe = valueWithPipes.RemoveFirstInstanceOfString("|");
//Output, valueWithoutFirstpipe = " 1 | 2 | 3";
灵感来自@LukeH和@Mike的答案,并对其进行了修改。
别忘了StringComparison.Ordinal来防止区域性设置出现问题。 https://www.jetbrains.com/help/resharper/2018.2/StringIndexOfIsCultureSpecific.1.html