2011-04-05 49 views
17

我最近不得不在.net中執行一些字符串替換,並發現自己正在爲此目的開發一個正則表達式替換函數。在啓用它之後,我忍不住想在.Net中必須有一個內置的不區分大小寫的替換操作,我錯過了?沒有使用正則表達式在.NET中是否有不區分大小寫的字符串替換?

當然,當有太多的其他字符串操作支持不區分大小寫的比較時,比如;

var compareStrings = String.Compare("a", "b", blIgnoreCase); 
var equalStrings = String.Equals("a", "b", StringComparison.CurrentCultureIgnoreCase); 

則必須有一個內置的等效替代?

+0

看一看這裏的討論:http://stackoverflow.com/questions/244531/is-there-an-alternative-to-string-replace-that-is-case-insensitive。有一個擴展方法的例子,它會做你想做的。 – 2011-04-05 09:04:29

+0

@RB:謝謝,這是「擴展」.Net功能的好方法,但我的查詢是關於是否有內置方法。儘管我會用這個例子來包裝我的Regex replace,歡呼聲。 – 2011-04-05 09:27:32

回答

20

找到一個在這裏評論:http://www.codeproject.com/Messages/1835929/this-one-is-even-faster-and-more-flexible-modified.aspx

static public string Replace(string original, string pattern, string replacement, StringComparison comparisonType) 
{ 
    return Replace(original, pattern, replacement, comparisonType, -1); 
} 

static public string Replace(string original, string pattern, string replacement, StringComparison comparisonType, int stringBuilderInitialSize) 
{ 
    if (original == null) 
    { 
     return null; 
    } 

    if (String.IsNullOrEmpty(pattern)) 
    { 
     return original; 
    } 


    int posCurrent = 0; 
    int lenPattern = pattern.Length; 
    int idxNext = original.IndexOf(pattern, comparisonType); 
    StringBuilder result = new StringBuilder(stringBuilderInitialSize < 0 ? Math.Min(4096, original.Length) : stringBuilderInitialSize); 

    while (idxNext >= 0) 
    { 
     result.Append(original, posCurrent, idxNext - posCurrent); 
     result.Append(replacement); 

     posCurrent = idxNext + lenPattern; 

     idxNext = original.IndexOf(pattern, posCurrent, comparisonType); 
     } 

     result.Append(original, posCurrent, original.Length - posCurrent); 

     return result.ToString(); 
} 

應該是最快的,但我沒有檢查。

否則,你應該做西蒙建議和使用VisualBasic Replace函數。這是我總是做的,因爲它的大小寫不敏感的功能(我通常是一個VB.Net程序員)。

string s = "SoftWare"; 
s = Microsoft.VisualBasic.Strings.Replace(s, "software", "hardware", 1, -1, Constants.vbTextCompare); 

您必須添加對Microsoft.VisualBasic dll的引用。

+0

感謝您的全面細分。所以看起來好像沒有內置的.Net機制,至少現在我自己感覺不錯。乾杯。 – 2011-04-05 09:28:11

+0

注意非序數比較類型:由於''匹配'AE'或'ß'匹配'SS'等事物,實際要替換的部分實際上可能與'oldValue'實際上沒有相同的長度...並且我不知道等價於'IndexOf()',它將返回實際匹配的部分的長度... – Medinoc 2014-09-18 13:25:21

+3

@BrianScott:VisualBasic名稱空間是.net運行時的一部分,它不僅限於VB 。從C#(或F#)項目引用它是很好的。它被命名爲歷史原因,但它沒有cooties。 – jmoreno 2015-04-11 21:09:12

12

這並不理想,但您可以導入Microsoft.VisualBasic並使用Strings.Replace來執行此操作。否則,我認爲這是滾動你自己或堅持正則表達式的情況。

0

那麼,內置的String.Replace只是不支持不區分大小寫的搜索。它的記錄:

此方法執行序 (區分大小寫和 文化不敏感)搜索找到 屬性oldValue。

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

它不應該是,不過,太難創建自己的擴展。

3

這裏有一個擴展方法。不知道我在哪裏找到它。

public static class StringExtensions 
{ 
    public static string Replace(this string originalString, string oldValue, string newValue, StringComparison comparisonType) 
    { 
     int startIndex = 0; 
     while (true) 
     { 
      startIndex = originalString.IndexOf(oldValue, startIndex, comparisonType); 
      if (startIndex == -1) 
       break; 

      originalString = originalString.Substring(0, startIndex) + newValue + originalString.Substring(startIndex + oldValue.Length); 

      startIndex += newValue.Length; 
     } 

     return originalString; 
    } 

} 
+1

此代碼缺少一些重要的檢查(如果oldValue爲空,則無限循環)。 – 2016-10-21 12:35:46

+0

如果originalString和oldValue都爲空,也會發生無限循環。如果originalString爲空,那麼沒有東西可以替換,所以需要檢查originalString爲空。還需要檢查空字符串。否則這個效果很好。我已經翻譯成VB.NET併發布爲答案。 – 2016-11-11 02:14:08

+0

更不用說返回「originalString」對於代碼可讀性來說很糟糕... – menssana 2017-03-23 13:38:18

-1

返回所指定的子已替換爲另一個子倍
它有一個可選的Microsoft.VisualBasic.CompareMethod paramater指定的那種比較的評估子

時使用指定的數字的字符串
Dim mystring As String = "One Two Three" 
    mystring = Replace(mystring, "two", "TWO", 1, , CompareMethod.Text) 
+1

請添加一些解釋。 – DontVoteMeDown 2013-12-27 12:17:23

0

我知道框架中沒有固定的實例,但這裏有另一個擴展方法版本,其中包含最少量的語句(雖然可能不是最快的),爲了好玩。更多版本的替換函數也發佈在http://www.codeproject.com/KB/string/fastestcscaseinsstringrep.aspx和「Is there an alternative to string.Replace that is case-insensitive?」。

public static string ReplaceIgnoreCase(this string alterableString, string oldValue, string newValue){ 
    if(alterableString == null) return null; 
    for(
     int i = alterableString.IndexOf(oldValue, System.StringComparison.CurrentCultureIgnoreCase); 
     i > -1; 
     i = alterableString.IndexOf(oldValue, i+newValue.Length, System.StringComparison.CurrentCultureIgnoreCase) 
    ) alterableString = 
     alterableString.Substring(0, i) 
     +newValue 
     +alterableString.Substring(i+oldValue.Length) 
    ; 
    return alterableString; 
} 
0

我的2美分:

public static string Replace(this string originalString, string oldValue, string newValue, StringComparison comparisonType) 
{ 
    if (originalString == null) 
     return null; 
    if (oldValue == null) 
     throw new ArgumentNullException("oldValue"); 
    if (oldValue == string.Empty) 
     return originalString; 
    if (newValue == null) 
     throw new ArgumentNullException("newValue"); 

    const int indexNotFound = -1; 
    int startIndex = 0, index = 0; 
    while ((index = originalString.IndexOf(oldValue, startIndex, comparisonType)) != indexNotFound) 
    { 
     originalString = originalString.Substring(0, index) + newValue + originalString.Substring(index + oldValue.Length); 
     startIndex = index + newValue.Length; 
    } 

    return originalString; 
} 



Replace("FOOBAR", "O", "za", StringComparison.OrdinalIgnoreCase); 
// "FzazaBAR" 

Replace("", "O", "za", StringComparison.OrdinalIgnoreCase); 
// "" 

Replace("FOO", "BAR", "", StringComparison.OrdinalIgnoreCase); 
// "FOO" 

Replace("FOO", "F", "", StringComparison.OrdinalIgnoreCase); 
// "OO" 

Replace("FOO", "", "BAR", StringComparison.OrdinalIgnoreCase); 
// "FOO" 
1

這是一個用VB。NET對rboarman方法進行適應性調整,並對空字符串和空字符串進行必要的檢查以避免無限循環。

Public Function Replace(ByVal originalString As String, ByVal oldValue As String, newValue As String, ByVal comparisonType As StringComparison) As String 
    If String.IsNullOrEmpty(originalString) = False AndAlso String.IsNullOrEmpty(oldValue) = False AndAlso IsNothing(newValue) = False Then 
     Dim startIndex As Int32 

     Do While True 
      startIndex = originalString.IndexOf(oldValue, startIndex, comparisonType) 
      If startIndex = -1 Then Exit Do 
      originalString = originalString.Substring(0, startIndex) & newValue & originalString.Substring(startIndex + oldValue.Length) 
      startIndex += newValue.Length 
     Loop 
    End If 

    Return originalString 
End Function 
相關問題