मुझे अपना मामला बनाने दो और फिर तुम चाहो तो मुझे किनारे तक फाड़ सकते हो।
रेगेक्स इस समस्या का जवाब नहीं है - बहुत धीमी और स्मृति भूख, अपेक्षाकृत बोल।
स्ट्रिंग मैनबलिंग की तुलना में स्ट्रिंगबर्ल बहुत बेहतर है।
चूंकि यह पूरक करने के लिए एक विस्तार विधि होगी string.Replace
, इसलिए मुझे विश्वास है कि यह मैच के लिए महत्वपूर्ण है कि कैसे काम करता है - इसलिए एक ही तर्क के मुद्दों के लिए अपवाद फेंकना महत्वपूर्ण है क्योंकि मूल स्ट्रिंग वापस आ रही है यदि प्रतिस्थापन नहीं किया गया था।
मेरा मानना है कि StringComparison पैरामीटर होना एक अच्छा विचार नहीं है। मैंने इसे आजमाया लेकिन मूल रूप से माइकल-ली द्वारा उल्लिखित परीक्षण मामले में एक समस्या दिखाई दी: -
[TestCase("œ", "oe", "", StringComparison.InvariantCultureIgnoreCase, Result = "")]
जब भी IndexOf मैच करेगा, स्रोत स्ट्रिंग (1) और oldValue.Length (2) में मैच की लंबाई के बीच एक बेमेल है। जब OldValue.Length वर्तमान मैच की स्थिति में जोड़ा गया था और मैं इस के आसपास एक रास्ता नहीं मिल सकता है कुछ अन्य समाधान में IndexOutOfRange के कारण से ही प्रकट हुआ। रेगेक्स वैसे भी मामले से मेल नहीं खाता है, इसलिए मैंने केवल StringComparison.OrdinalIgnoreCase
अपने समाधान के लिए उपयोग करने का व्यावहारिक समाधान लिया ।
मेरा कोड अन्य उत्तरों के समान है, लेकिन मेरा ट्विस्ट यह है कि मैं एक मैच बनाने से पहले एक मैच की तलाश में हूं StringBuilder
। यदि कोई नहीं मिला तो संभावित रूप से बड़े आवंटन से बचा जाता है। कोड तो एक do{...}while
नहीं बल्कि एक हो जाता हैwhile{...}
मैंने अन्य उत्तरों के खिलाफ कुछ व्यापक परीक्षण किया है और यह आंशिक रूप से तेजी से निकला है और थोड़ी कम मेमोरी का उपयोग किया है।
public static string ReplaceCaseInsensitive(this string str, string oldValue, string newValue)
{
if (str == null) throw new ArgumentNullException(nameof(str));
if (oldValue == null) throw new ArgumentNullException(nameof(oldValue));
if (oldValue.Length == 0) throw new ArgumentException("String cannot be of zero length.", nameof(oldValue));
var position = str.IndexOf(oldValue, 0, StringComparison.OrdinalIgnoreCase);
if (position == -1) return str;
var sb = new StringBuilder(str.Length);
var lastPosition = 0;
do
{
sb.Append(str, lastPosition, position - lastPosition);
sb.Append(newValue);
} while ((position = str.IndexOf(oldValue, lastPosition = position + oldValue.Length, StringComparison.OrdinalIgnoreCase)) != -1);
sb.Append(str, lastPosition, str.Length - lastPosition);
return sb.ToString();
}