Davamı yapmama izin verin ve sonra beni dilerseniz parçalara ayırabilirsiniz.
Regex bu sorunun cevabı değildir - nispeten yavaş ve çok aç ve hafıza aç.
StringBuilder, string mangling'den çok daha iyidir.
Bu, ek bir uzantı yöntemi olacağından string.Replace
, bunun nasıl çalıştığını eşleştirmenin önemli olduğuna inanıyorum - bu nedenle, aynı argüman sorunları için istisnalar atmak, bir değiştirme yapılmadıysa orijinal dizeyi döndürmek kadar önemlidir.
Bir StringComparison parametresi olması iyi bir fikir olmadığına inanıyorum. Ben denedim ama michael-liu tarafından belirtilen test durumda bir sorun gösterdi: -
[TestCase("œ", "oe", "", StringComparison.InvariantCultureIgnoreCase, Result = "")]
IndexOf eşleşirken, kaynak dizgideki (1) eşleşmenin uzunluğu ile oldValue.Length (2) arasında bir uyumsuzluk vardır. Bu, oldValue.Length geçerli eşleme konumuna eklendiğinde bazı diğer çözümlerde IndexOutOfRange'a neden olarak kendini gösterdi ve bunun etrafında bir yol bulamadım. Regex yine de davaya uymuyor, bu yüzden sadece çözümüm için kullanmanın pragmatik çözümünü StringComparison.OrdinalIgnoreCase
aldım.
Kodum diğer cevaplara benzer, ancak benim büküm bir oluşturma sorunu gitmeden önce bir maç aramak olduğunu StringBuilder
. Hiçbiri bulunmazsa, potansiyel olarak büyük bir ayırmadan kaçınılır. Kod daha sonra do{...}while
birwhile{...}
Diğer Yanıtlara karşı bazı kapsamlı testler yaptım ve bu fraksiyonel olarak daha hızlı çıktı ve biraz daha az bellek kullandı.
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();
}