Saya tahu bahwa yang berikut ini peka huruf besar-kecil:
if (StringA == StringB) {
Jadi adakah operator yang akan membandingkan dua string dengan cara yang tidak sensitif?
~=
dengan paralel ==
sebagai versi case-insensitive
Saya tahu bahwa yang berikut ini peka huruf besar-kecil:
if (StringA == StringB) {
Jadi adakah operator yang akan membandingkan dua string dengan cara yang tidak sensitif?
~=
dengan paralel ==
sebagai versi case-insensitive
Jawaban:
Coba ini:
string.Equals(a, b, StringComparison.CurrentCultureIgnoreCase);
if A$=B$ then goto 10
"
Cara terbaik untuk membandingkan 2 string dengan mengabaikan huruf-huruf adalah dengan menggunakan String. Metode yang sama dengan yang menentukan perbandingan string case ordinal abaikan. Ini juga merupakan cara tercepat, jauh lebih cepat daripada mengubah string menjadi huruf besar atau kecil dan membandingkannya setelah itu.
Saya menguji kinerja kedua pendekatan dan perbandingan string case ordinal Abaikan lebih dari 9 kali lebih cepat ! Ini juga lebih dapat diandalkan daripada mengubah string menjadi huruf besar atau kecil (lihat masalah Turki i). Jadi selalu gunakan metode String.Equals untuk membandingkan string untuk kesetaraan:
String.Equals(string1, string2, StringComparison.OrdinalIgnoreCase);
Jika Anda ingin melakukan perbandingan string khusus budaya Anda dapat menggunakan kode berikut:
String.Equals(string1, string2, StringComparison.CurrentCultureIgnoreCase);
Harap perhatikan bahwa contoh kedua menggunakan logika perbandingan string dari budaya saat ini, yang membuatnya lebih lambat daripada perbandingan "kasus abaikan ordinal" dalam contoh pertama, jadi jika Anda tidak memerlukan logika perbandingan string budaya tertentu dan Anda setelah kinerja maksimum, gunakan perbandingan "kasus abaikan ordinal".
Untuk informasi lebih lanjut, baca kisah lengkapnya di blog saya .
ToLower
atau ToLowerInvariant
: mereka membuat memori hanya untuk melakukan perbandingan, dan mereka mungkin gagal karena set karakter baru ditambahkan ke unicode. ToUpper
gagal karena bahasa Turki 'i', antara lain; tidak ada alasan mengapa ToLower
tidak akan gagal di masa depan karena alasan yang sama.
ToLower
atau ToLowerInvariant
metode, saya hanya ingin menunjukkan betapa jauh lebih efisien String.Equals
metode ini
Ada sejumlah properti di StringComparer
kelas statis yang mengembalikan pembanding untuk semua jenis sensitivitas huruf yang mungkin Anda inginkan:
Misalnya, Anda dapat menelepon
StringComparer.CurrentCultureIgnoreCase.Equals(string1, string2)
atau
StringComparer.CurrentCultureIgnoreCase.Compare(string1, string2)
Itu sedikit lebih bersih daripada string.Equals
atau string.Compare
kelebihan yang mengambil StringComparison
argumen.
System.Collections.CaseInsensitiveComparer
atau
System.StringComparer.OrdinalIgnoreCase
atau
if (StringA.Equals(StringB, StringComparison.CurrentCultureIgnoreCase)) {
tetapi Anda harus yakin bahwa StringA bukan nol. Jadi mungkin lebih baik kamu gunakan:
string.Equals(StringA , StringB, StringComparison.CurrentCultureIgnoreCase);
seperti yang disarankan John
EDIT: memperbaiki bug
Kamu bisa memakai
if (stringA.equals(StringB, StringComparison.CurrentCultureIgnoreCase))
Operator? TIDAK, tapi saya pikir Anda dapat mengubah budaya Anda sehingga perbandingan string tidak peka huruf besar-kecil.
// you'll want to change this...
System.Threading.Thread.CurrentThread.CurrentCulture
// and you'll want to custimize this
System.Globalization.CultureInfo.CompareInfo
Saya yakin itu akan mengubah cara string dibandingkan oleh operator yang sama.
Berikut ini ide untuk menyederhanakan sintaks:
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);
}
}
Dapat digunakan seperti:
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
) dan ambigu (Java memilih unboxing implisit vs tinju implisit jadi saya percaya ini tidak akan bekerja di Jawa dengan pemain implisit kembali ke string di sana). Dan ini menciptakan overhead memori dari 2 objek baru dengan eksekusi pohon panggilan untuk setiap perbandingan melompat ke beberapa metode panggilan bersarang untuk kasus penggunaan yang ditampilkan. Yang mengatakan, untuk sebagian besar kasus, kinerja mungkin cukup baik.
Saya sangat terbiasa mengetik di akhir metode perbandingan ini: , StringComparison.
Jadi saya membuat ekstensi.
namespace System
{ public static class StringExtension
{
public static bool Equals(this string thisString, string compareString,
StringComparison stringComparison)
{
return string.Equals(thisString, compareString, stringComparison);
}
}
}
Harap perhatikan bahwa Anda harus memeriksa nol thisString
sebelum memanggil ext.
string.Compare(string1, string2, true)
if (StringA.ToUpperInvariant() == StringB.ToUpperInvariant()) {
Orang melaporkan ToUpperInvariant () lebih cepat daripada ToLowerInvariant ().
Jawaban yang lain benar-benar valid di sini, tetapi entah bagaimana butuh waktu untuk mengetik StringComparison.OrdinalIgnoreCase
dan juga menggunakan String.Compare
.
Saya telah mengkodekan metode ekstensi String sederhana, di mana Anda dapat menentukan apakah perbandingan case-sensitive atau case-sensitive dengan boolean - lihat jawaban berikut: