Bagaimana saya melakukan hal sensitif perbandingan string di JavaScript?
EDIT: jawaban Ini awalnya menambahkan 9 tahun yang lalu. Hari ini anda harus menggunakan localeCompare
dengan sensitivitas: 'aksen'
pilihan:
function ciEquals(a, b) {
return typeof a === 'string' && typeof b === 'string'
? a.localeCompare(b, undefined, { sensitivity: 'accent' }) === 0
: a === b;
}
console.log("'a' = 'a'?", ciEquals('a', 'a'));
console.log("'AaA' = 'aAa'?", ciEquals('AaA', 'aAa'));
console.log("'a' = 'á'?", ciEquals('a', 'á'));
console.log("'a' = 'b'?", ciEquals('a', 'b'));
The { sensitivitas: 'aksen' }
memberitahu localeCompare()
untuk mengobati dua varian dasar yang sama huruf yang sama unless mereka memiliki aksen yang berbeda (seperti pada contoh ketiga) di atas.
Atau, anda dapat menggunakan { sensitivitas: 'dasar' }
, yang memperlakukan dua karakter sebagai setara sebagai panjang sebagai basis karakter yang sama (sehingga A
akan diperlakukan sebagai setara dengan á
).
Catatan yang ketiga parameter localeCompare
tidak didukung di IE10 atau lebih rendah atau beberapa browser mobile (lihat grafik kompatibilitas pada halaman terkait di atas), jadi jika anda perlu untuk dukungan browser tersebut, anda'll memerlukan beberapa jenis mundur:
function ciEqualsInner(a, b) {
return a.localeCompare(b, undefined, { sensitivity: 'accent' }) === 0;
}
function ciEquals(a, b) {
if (typeof a !== 'string' || typeof b !== 'string') {
return a === b;
}
// v--- feature detection
return ciEqualsInner('A', 'a')
? ciEqualsInner(a, b)
: /* fallback approach here */;
}
Jawaban asli
Cara terbaik untuk melakukan hal sensitif dibandingkan di JavaScript adalah dengan menggunakan RegExp match()
metode i
bendera.
https://stackoverflow.com/questions/177719/javascript-case-insensitive-search
Ketika kedua string yang dibandingkan adalah variabel (tidak konstan), maka's sedikit lebih rumit 'penyebab yang anda butuhkan untuk menghasilkan RegExp dari string tapi lewat string untuk RegExp konstruktor dapat mengakibatkan kesalahan cocok atau gagal sesuai jika string khusus regex karakter-karakter di dalamnya.
Jika anda peduli tentang internasionalisasi don't menggunakan toLowerCase()
atau toUpperCase()
seperti itu doesn't memberikan informasi yang akurat case-sensitive perbandingan dalam semua bahasa.
Dengan bantuan dari ekspresi reguler juga bisa kita capai.
(/keyword/i).test(source)
/i
adalah untuk mengabaikan kasus ini. Jika tidak diperlukan, kita dapat mengabaikan dan tes untuk TIDAK case sensitif pertandingan seperti
(/keyword/).test(source)
Ingat bahwa casing lokal operasi tertentu. Tergantung pada skenario yang mungkin anda ingin mengambil ke account. Misalnya, jika anda membandingkan nama-nama dari dua orang yang anda mungkin ingin mempertimbangkan untuk lokal tapi jika anda membandingkan nilai-nilai yang dihasilkan mesin seperti UUID maka anda mungkin tidak. Ini mengapa saya menggunakan fungsi berikut saya utils perpustakaan (perhatikan bahwa jenis pemeriksaan ini tidak termasuk untuk alasan kinerja).
function compareStrings (string1, string2, ignoreCase, useLocale) {
if (ignoreCase) {
if (useLocale) {
string1 = string1.toLocaleLowerCase();
string2 = string2.toLocaleLowerCase();
}
else {
string1 = string1.toLowerCase();
string2 = string2.toLowerCase();
}
}
return string1 === string2;
}
Seperti dikatakan dalam komentar terbaru, string::localCompare
mendukung kasus sensitif perbandingan (antara lain hal-hal yang kuat).
Berikut ini's contoh sederhana
'xyz'.localeCompare('XyZ', undefined, { sensitivity: 'base' }); // returns 0
Dan fungsi generik bisa anda gunakan
function equalsIgnoringCase(text, other) {
return text.localeCompare(other, undefined, { sensitivity: 'base' }) === 0;
}
Perhatikan bahwa bukan undefined
anda mungkin harus memasukkan kode tertentu lokal anda bekerja dengan. Hal ini penting karena dilambangkan di MDN docs
di swedia, ä dan terpisah dasar surat
Pada saat posting, UC Browser for Android dan Opera Mini tidak dukungan locale dan options parameter. Silakan cek https://caniuse.com/#search=localeCompare untuk info terkini.
Saya baru saja membuat sebuah micro perpustakaan yang menyediakan case-sensitive string pembantu: https://github.com/nickuraltsev/ignore-case. (Menggunakan toUpperCase
internal.)
var ignoreCase = require('ignore-case');
ignoreCase.equals('FOO', 'Foo'); // => true
ignoreCase.startsWith('foobar', 'FOO'); // => true
ignoreCase.endsWith('foobar', 'BaR'); // => true
ignoreCase.includes('AbCd', 'c'); // => true
ignoreCase.indexOf('AbCd', 'c'); // => 2
jika anda khawatir tentang arah ketimpangan (mungkin anda ingin mengurutkan daftar) anda cukup-banyak harus melakukan hal-konversi, dan karena ada yang lebih kecil karakter dalam unicode dari huruf besar toLowerCase adalah mungkin konversi terbaik untuk digunakan.
function my_strcasecmp( a, b )
{
if((a+'').toLowerCase() > (b+'').toLowerCase()) return 1
if((a+'').toLowerCase() < (b+'').toLowerCase()) return -1
return 0
}
Javascript tampaknya menggunakan lokal "C" untuk perbandingan string sehingga dihasilkan akan memesan menjadi jelek jika string mengandung lain dari huruf ASCII. ada's tidak banyak yang dapat dilakukan tentang itu tanpa melakukan banyak pemeriksaan rinci dari string.
Misalkan kita ingin menemukan variabel string jarum
di variabel string jerami
. Ada tiga gotchas:
string.toUpperCase
dan string.toLowerCase
. Menggunakan ekspresi reguler yang mengabaikan hal sebaliknya. Misalnya, var needleRegExp = new RegExp(jarum, "aku");
diikuti oleh needleRegExp.tes(jerami)
.jarum
. Hati-hati bahwa jarum
tidak mengandung ekspresi reguler karakter khusus. Melarikan diri ini menggunakan jarum.mengganti(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
.jarum
dan jerami
, hanya mengabaikan hal ini, pastikan untuk menambahkan "^"
di awal dan "$"
pada akhir dari ekspresi reguler anda konstruktor.Mengambil poin (1) dan (2) menjadi pertimbangan, contohnya:
var haystack = "A. BAIL. Of. Hay.";
var needle = "bail.";
var needleRegExp = new RegExp(needle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), "i");
var result = needleRegExp.test(haystack);
if (result) {
// Your code here
}
Ada dua cara untuk case sensitive perbandingan:
===
). Bagaimana ketat operator memperlakukan operan membaca hal-hal di:
http://www.thesstech.com/javascript/relational-logical-operatorsGunakan "pencarian" string metode untuk kasus sensitif cari. Baca tentang pencarian dan string lain metode di: http://www.thesstech.com/pattern-matching-using-string-methods
<!doctype html>
<html>
<head>
<script>
// 1st way
var a = "apple";
var b = "APPLE";
if (a.toUpperCase() === b.toUpperCase()) {
alert("equal");
}
//2nd way
var a = " Null and void";
document.write(a.search(/null/i));
</script>
</head>
</html>
Banyak jawaban di sini, tapi saya ingin menambahkan solusi berdasarkan memperpanjang String lib:
String.prototype.equalIgnoreCase = function(str)
{
return (str != null
&& typeof str === 'string'
&& this.toUpperCase() === str.toUpperCase());
}
Dengan cara ini anda hanya dapat menggunakannya seperti yang anda lakukan di pulau Jawa!
Contoh:
var a = "hello";
var b = "HeLLo";
var c = "world";
if (a.equalIgnoreCase(b)) {
document.write("a == b");
}
if (a.equalIgnoreCase(c)) {
document.write("a == c");
}
if (!b.equalIgnoreCase(c)) {
document.write("b != c");
}
Output akan sama:
"a == b"
"b != c"
String.prototype.equalIgnoreCase = function(str) {
return (str != null &&
typeof str === 'string' &&
this.toUpperCase() === str.toUpperCase());
}
var a = "hello";
var b = "HeLLo";
var c = "world";
if (a.equalIgnoreCase(b)) {
document.write("a == b");
document.write("<br>");
}
if (a.equalIgnoreCase(c)) {
document.write("a == c");
}
if (!b.equalIgnoreCase(c)) {
document.write("b != c");
}
str = 'Lol', str2 = 'lOl', regex = new RegExp('^' + str + '$', 'i');
if (regex.test(str)) {
console.log("true");
}
Jika kedua string sama-sama dikenal lokal, anda mungkin ingin menggunakan Intl.Collator
objek seperti ini:
function equalIgnoreCase(s1: string, s2: string) {
return new Intl.Collator("en-US", { sensitivity: "base" }).compare(s1, s2) === 0;
}
Jelas, anda mungkin ingin men-cache Collator
untuk efisiensi yang lebih baik.
Keuntungan dari pendekatan ini adalah bahwa hal itu harus jauh lebih cepat daripada menggunakan RegExps dan didasarkan pada aplikasi yang sangat disesuaikan (lihat keterangan dari terkenal
dan pilihan
parameter konstruktor dalam artikel di atas) set siap-untuk-menggunakan collators.
Bahkan pertanyaan ini sudah dijawab. Saya memiliki pendekatan yang berbeda untuk menggunakan RegExp dan cocok untuk mengabaikan kasus sensitif. Silahkan melihat link saya
$("#btnGuess").click(guessWord);
function guessWord() {
var letter = $("#guessLetter").val();
var word = 'ABC';
var pattern = RegExp(letter, 'gi'); // pattern: /a/gi
var result = word.match(pattern);
alert('Ignore case sensitive:' + result);
}
Menggunakan RegEx untuk string pertandingan atau perbandingan.
Dalam JavaScript, anda dapat menggunakan match()
untuk perbandingan string,
don't lupa untuk menempatkan `aku ' di RegEx.
Contoh:
var matchString = "Test";
if (matchString.match(/test/i)) {
alert('String matched');
}
else {
alert('String not matched');
}
Karena tidak ada jawaban jelas yang disediakan snippet kode sederhana untuk menggunakan RegExp
, di sini's my upaya:
function compareInsensitive(str1, str2){
return typeof str1 === 'string' &&
typeof str2 === 'string' &&
new RegExp("^" + str1.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + "$", "i").test(str2);
}
Ini memiliki beberapa keuntungan:
undefined
misalnya, akan crash ekspresi seperti str1.toUpperCase()
).RegExp
string.Bagaimana TIDAK melemparkan pengecualian dan TIDAK menggunakan slow regex?
return str1 != null && str2 != null
&& typeof str1 === 'string' && typeof str2 === 'string'
&& str1.toUpperCase() === str2.toUpperCase();
Potongan di atas mengasumsikan anda don't ingin mencocokkan jika kedua string adalah null atau tidak terdefinisi.
Jika anda ingin mencocokkan null/undefined, maka:
return (str1 == null && str2 == null)
|| (str1 != null && str2 != null
&& typeof str1 === 'string' && typeof str2 === 'string'
&& str1.toUpperCase() === str2.toUpperCase());
Jika untuk beberapa alasan anda peduli tentang terdefinisi vs null:
return (str1 === undefined && str2 === undefined)
|| (str1 === null && str2 === null)
|| (str1 != null && str2 != null
&& typeof str1 === 'string' && typeof str2 === 'string'
&& str1.toUpperCase() === str2.toUpperCase());
Ini adalah versi perbaikan dari jawaban ini.
String.equal = function (s1, s2, ignoreCase, useLocale) {
if (s1 == null || s2 == null)
return false;
if (!ignoreCase) {
if (s1.length !== s2.length)
return false;
return s1 === s2;
}
if (useLocale) {
if (useLocale.length)
return s1.toLocaleLowerCase(useLocale) === s2.toLocaleLowerCase(useLocale)
else
return s1.toLocaleLowerCase() === s2.toLocaleLowerCase()
}
else {
if (s1.length !== s2.length)
return false;
return s1.toLowerCase() === s2.toLowerCase();
}
}
String.equal = function (s1, s2, ignoreCase, useLocale) {
if (s1 == null || s2 == null)
return false;
if (!ignoreCase) {
if (s1.length !== s2.length)
return false;
return s1 === s2;
}
if (useLocale) {
if (useLocale.length)
return s1.toLocaleLowerCase(useLocale) === s2.toLocaleLowerCase(useLocale)
else
return s1.toLocaleLowerCase() === s2.toLocaleLowerCase()
}
else {
if (s1.length !== s2.length)
return false;
return s1.toLowerCase() === s2.toLowerCase();
}
}
// If you don't mind extending the prototype.
String.prototype.equal = function(string2, ignoreCase, useLocale) {
return String.equal(this.valueOf(), string2, ignoreCase, useLocale);
}
// ------------------ TESTS ----------------------
console.log("Tests...");
console.log('Case sensitive 1');
var result = "Abc123".equal("Abc123");
console.assert(result === true);
console.log('Case sensitive 2');
result = "aBC123".equal("Abc123");
console.assert(result === false);
console.log('Ignore case');
result = "AbC123".equal("aBc123", true);
console.assert(result === true);
console.log('Ignore case + Current locale');
result = "AbC123".equal("aBc123", true);
console.assert(result === true);
console.log('Turkish test 1 (ignore case, en-US)');
result = "IiiI".equal("ıiİI", true, "en-US");
console.assert(result === false);
console.log('Turkish test 2 (ignore case, tr-TR)');
result = "IiiI".equal("ıiİI", true, "tr-TR");
console.assert(result === true);
console.log('Turkish test 3 (case sensitive, tr-TR)');
result = "IiiI".equal("ıiİI", false, "tr-TR");
console.assert(result === false);
console.log('null-test-1');
result = "AAA".equal(null);
console.assert(result === false);
console.log('null-test-2');
result = String.equal(null, "BBB");
console.assert(result === false);
console.log('null-test-3');
result = String.equal(null, null);
console.assert(result === false);
Mengkonversi ke yang lebih rendah (hanya sekali untuk alasan kinerja) dan membandingkannya dengan operator ternary dalam satu baris:
function strcasecmp(s1,s2){
s1=(s1+'').toLowerCase();
s2=(s2+'').toLowerCase();
return s1>s2?1:(s1<s2?-1:0);
}