2010-02-04 96 views
54

我需要從另一個字符串中刪除第一個(也是唯一的第一個)字符串。C# - 從另一個字符串中刪除第一個子字符串的最簡單方法

以下是替換字符串"\\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; 

這似乎是一個大量的代碼。

所以我的問題是:是否有一個更清潔/更可讀/更簡潔的方式來做到這一點?

回答

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

對於涉及非ASCII字符的字符串,此答案可能會中斷。例如,在美國文化下,'æ'和'ae'被認爲是平等的。嘗試從'Encyclopædia'中刪除'paedia'將會拋出一個'ArgumentOutOfRangeException',因爲當匹配的子字符串只包含5時你試圖刪除6個字符。 – Douglas 2016-02-18 15:13:43

+1

我們可以這樣修改它:'sourceString.IndexOf(removeString,StringComparison。 Ordinal)'以避免例外。 – 2016-12-20 19:37:57

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

編輯:@OregonGhost是正確的。我自己會用條件來打破劇本來檢查這樣的事件,但是我的操作是根據一些要求給出的字符串屬於彼此。業務所需的異常處理規則可能有望實現這種可能性。我自己會使用一些額外的行來執行有條件的檢查,並且對於那些可能沒有花時間仔細閱讀它的初級開發人員來說,它會使它更具可讀性。

+6

這將崩潰,如果removeString不sourceString遏制。 – OregonGhost 2010-02-04 17:13:08

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(輸入 「」,1);說要在輸入中查找與該模式匹配的任何內容,用「」,1次。

+2

就像你解決了這個問題。當使用正則表達式來解決像這樣的問題時,請考慮性能。 – Thomas 2012-10-16 15:32:55

6

您可以使用擴展方法來獲得樂趣。通常我不建議將擴展方法附加到像字符串這樣的通用類,但就像我說的這很有趣。我借鑑了盧克的回答,因爲重新發明車輪毫無意義。

[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); 
    } 
} 
+0

爲什麼你通常不建議將擴展方法附加到像String這樣的通用類?這有什麼明顯的缺點? – 2017-10-11 09:55:01

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); 

    } 
12
sourceString.Replace(removeString, ""); 
+7

[String.Replace](https://msdn.microsoft.com/en-us/library/fk49wtc1%28v=vs.110%29.aspx)說,它「* [r] eturns一個新的字符串,其中所有當前實例中指定字符串的出現被替換爲另一個指定的字符串*「。 OP想要替換**第一次**事件。 – 2015-08-04 08:42:01

+2

另外,您應該解釋一下您的答案,因爲僅有代碼的答案是不可接受的。看看其他答案,並將它們與你的一些提示進行比較。 – 2015-08-04 08:43:23

相關問題