Hãy để tôi làm cho trường hợp của tôi và sau đó bạn có thể xé tôi thành mảnh vụn nếu bạn muốn.
Regex không phải là câu trả lời cho vấn đề này - quá chậm và bộ nhớ đói, nói một cách tương đối.
StringBuilder tốt hơn nhiều so với xâu chuỗi.
Vì đây sẽ là một phương thức mở rộng để bổ sung string.Replace
, tôi tin rằng điều quan trọng là phải khớp với cách thức hoạt động - do đó, việc đưa ra các ngoại lệ cho cùng một vấn đề đối số cũng quan trọng như trả về chuỗi gốc nếu không thực hiện thay thế.
Tôi tin rằng có một tham số StringComparison không phải là một ý tưởng tốt. Tôi đã thử nhưng trường hợp thử nghiệm ban đầu được đề cập bởi michael-liu cho thấy một vấn đề: -
[TestCase("œ", "oe", "", StringComparison.InvariantCultureIgnoreCase, Result = "")]
Trong khi IndexOf sẽ khớp, có sự không khớp giữa độ dài của trận đấu trong chuỗi nguồn (1) và oldValue.Lipse (2). Điều này thể hiện bằng cách gây ra IndexOutOfRange trong một số giải pháp khác khi oldValue.Lipse được thêm vào vị trí khớp hiện tại và tôi không thể tìm ra cách nào khác. Regex không khớp với trường hợp nào, vì vậy tôi đã sử dụng giải pháp thực tế là chỉ sử dụngStringComparison.OrdinalIgnoreCase
cho giải pháp của mình.
Mã của tôi tương tự như các câu trả lời khác nhưng điều khó khăn của tôi là tôi tìm kiếm một trận đấu trước khi gặp rắc rối khi tạo một StringBuilder
. Nếu không tìm thấy thì phân bổ có khả năng lớn sẽ tránh được. Mã sau đó trở thành một do{...}while
chứ không phải là mộtwhile{...}
Tôi đã thực hiện một số thử nghiệm mở rộng đối với các Câu trả lời khác và điều này xuất hiện nhanh hơn một chút và sử dụng ít bộ nhớ hơn.
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();
}