Tôi biết rằng sau đây là trường hợp nhạy cảm:
if (StringA == StringB) {
Vì vậy, có một toán tử sẽ so sánh hai chuỗi một cách không nhạy cảm?
~=
với song song ==
như một phiên bản không phân biệt chữ hoa chữ thường.
Tôi biết rằng sau đây là trường hợp nhạy cảm:
if (StringA == StringB) {
Vì vậy, có một toán tử sẽ so sánh hai chuỗi một cách không nhạy cảm?
~=
với song song ==
như một phiên bản không phân biệt chữ hoa chữ thường.
Câu trả lời:
Thử cái này:
string.Equals(a, b, StringComparison.CurrentCultureIgnoreCase);
if A$=B$ then goto 10
"
Cách tốt nhất để so sánh 2 chuỗi bỏ qua trường hợp của các chữ cái là sử dụng phương thức tĩnh String.Equals chỉ định so sánh chuỗi trường hợp bỏ qua thứ tự. Đây cũng là cách nhanh nhất, nhanh hơn nhiều so với chuyển đổi chuỗi thành chữ thường hoặc chữ hoa và so sánh chúng sau đó.
Tôi đã thử nghiệm hiệu suất của cả hai phương pháp và so sánh chuỗi trường hợp bỏ qua thứ tự nhanh hơn 9 lần ! Nó cũng đáng tin cậy hơn so với chuyển đổi chuỗi thành chữ thường hoặc chữ hoa (kiểm tra vấn đề i của Thổ Nhĩ Kỳ). Vì vậy, luôn luôn sử dụng phương thức String.Equals để so sánh các chuỗi cho đẳng thức:
String.Equals(string1, string2, StringComparison.OrdinalIgnoreCase);
Nếu bạn muốn thực hiện so sánh chuỗi văn hóa cụ thể, bạn có thể sử dụng mã sau:
String.Equals(string1, string2, StringComparison.CurrentCultureIgnoreCase);
Xin lưu ý rằng ví dụ thứ hai sử dụng logic so sánh chuỗi của văn hóa hiện tại, làm cho nó chậm hơn so với so sánh "trường hợp bỏ qua thứ tự" trong ví dụ đầu tiên, vì vậy nếu bạn không cần logic so sánh chuỗi cụ thể về văn hóa và bạn sau khi thực hiện tối đa, sử dụng so sánh "trường hợp bỏ qua thứ tự".
Để biết thêm thông tin, đọc toàn bộ câu chuyện trên blog của tôi .
ToLower
hoặc ToLowerInvariant
: họ tạo bộ nhớ chỉ để thực hiện so sánh và họ có thể thất bại khi các bộ ký tự mới được thêm vào unicode. ToUpper
thất bại vì 'i' của Thổ Nhĩ Kỳ, trong số những người khác; không có lý do tại sao ToLower
sẽ không thất bại trong tương lai vì những lý do tương tự.
ToLower
hoặc ToLowerInvariant
phương pháp, tôi chỉ muốn cho thấy String.Equals
phương pháp này hiệu quả hơn bao nhiêu .
Có một số thuộc tính trên StringComparer
lớp tĩnh trả về các so sánh cho bất kỳ loại phân biệt chữ hoa chữ thường nào bạn muốn:
Chẳng hạn, bạn có thể gọi
StringComparer.CurrentCultureIgnoreCase.Equals(string1, string2)
hoặc là
StringComparer.CurrentCultureIgnoreCase.Compare(string1, string2)
Nó sạch hơn một chút so với string.Equals
hoặc string.Compare
quá tải cần StringComparison
tranh luận.
System.Collections.CaseInsensitiveComparer
hoặc là
System.StringComparer.OrdinalIgnoreCase
Bạn có thể dùng
if (stringA.equals(StringB, StringComparison.CurrentCultureIgnoreCase))
Nhà điều hành? KHÔNG, nhưng tôi nghĩ bạn có thể thay đổi văn hóa của mình để so sánh chuỗi không phân biệt chữ hoa chữ thường.
// you'll want to change this...
System.Threading.Thread.CurrentThread.CurrentCulture
// and you'll want to custimize this
System.Globalization.CultureInfo.CompareInfo
Tôi tự tin rằng nó sẽ thay đổi cách các chuỗi được so sánh bởi toán tử bằng.
Đây là một ý tưởng để đơn giản hóa cú pháp:
public class IgnoreCase
{
private readonly string _value;
public IgnoreCase(string s)
{
_value = s;
}
protected bool Equals(IgnoreCase other)
{
return this == other;
}
public override bool Equals(object obj)
{
return obj != null &&
(ReferenceEquals(this, obj) || (obj.GetType() == GetType() && this == (IgnoreCase) obj));
}
public override int GetHashCode()
{
return _value?.GetHashCode() ?? 0;
}
public static bool operator ==(IgnoreCase a, IgnoreCase b)
{
return string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
}
public static bool operator !=(IgnoreCase a, IgnoreCase b)
{
return !(a == b);
}
public static implicit operator string(IgnoreCase s)
{
return s._value;
}
public static implicit operator IgnoreCase(string s)
{
return new IgnoreCase(s);
}
}
Có thể sử dụng như:
Console.WriteLine((IgnoreCase) "a" == "b"); // false
Console.WriteLine((IgnoreCase) "abc" == "abC"); // true
Console.WriteLine((IgnoreCase) "Abc" == "aBc"); // true
Console.WriteLine((IgnoreCase) "ABC" == "ABC"); // true
IgnoreCase
vs IgnoreCaseString
) và mơ hồ (Java chọn ẩn unboxing so với đấm bốc ngầm vì vậy tôi tin rằng điều này sẽ không hoạt động trong Java với hàm ẩn trong chuỗi đó). Và điều này tạo ra chi phí bộ nhớ của 2 đối tượng mới với thực thi cây cuộc gọi cho mỗi so sánh nhảy vào một số lệnh gọi phương thức lồng nhau cho trường hợp sử dụng được hiển thị. Điều đó nói rằng, đối với hầu hết các trường hợp, hiệu suất có thể là đủ tốt.
Tôi đã quá quen với việc gõ vào cuối các phương thức so sánh này: , StringComparison.
Vì vậy, tôi đã thực hiện một phần mở rộng.
namespace System
{ public static class StringExtension
{
public static bool Equals(this string thisString, string compareString,
StringComparison stringComparison)
{
return string.Equals(thisString, compareString, stringComparison);
}
}
}
Chỉ cần lưu ý rằng bạn sẽ cần kiểm tra null thisString
trước khi gọi máy lẻ.
string.Compare(string1, string2, true)
if (StringA.ToUpperInvariant() == StringB.ToUpperInvariant()) {
Mọi người báo cáo ToUpperInvariant () nhanh hơn ToLowerInvariant ().
Những câu trả lời khác hoàn toàn hợp lệ ở đây, nhưng bằng cách nào đó, bạn phải mất một thời gian để nhập StringComparison.OrdinalIgnoreCase
và sử dụng String.Compare
.
Tôi đã mã hóa phương thức mở rộng Chuỗi đơn giản, trong đó bạn có thể chỉ định nếu so sánh là phân biệt chữ hoa chữ thường hay chữ hoa chữ thường với boolean - xem câu trả lời sau: