Pencarian case-insensitive

272

Saya mencoba membuat pencarian case-insensitive dengan dua string di JavaScript berfungsi.

Biasanya akan seperti ini:

var string="Stackoverflow is the BEST";
var result= string.search(/best/i);
alert(result);

The /iflag akan untuk kasus-sensitif.

Tetapi saya perlu mencari string kedua; tanpa bendera itu berfungsi dengan sempurna:

var string="Stackoverflow is the BEST";
var searchstring="best";
var result= string.search(searchstring);
alert(result);

Jika saya menambahkan /iflag ke contoh di atas, ia akan mencari searchstring dan bukan untuk apa yang ada dalam variabel "searchstring" (contoh berikutnya tidak berfungsi):

var string="Stackoverflow is the BEST";
var searchstring="best";
var result= string.search(/searchstring/i);
alert(result);

Bagaimana saya bisa mencapai ini?

Chris Boesing
sumber

Jawaban:

373

Ya, gunakan .match, bukan .search. Hasil dari .matchpanggilan akan mengembalikan string aktual yang cocok dengan dirinya sendiri, tetapi masih dapat digunakan sebagai nilai boolean.

var string = "Stackoverflow is the BEST";
var result = string.match(/best/i);
// result == 'BEST';

if (result){
    alert('Matched');
}

Menggunakan ekspresi reguler seperti itu mungkin merupakan cara tersingkat dan paling jelas untuk melakukannya dalam JavaScript, tetapi ingatlah bahwa ini adalah ekspresi reguler, dan dengan demikian dapat berisi metacharacters regex. Jika Anda ingin mengambil string dari tempat lain (misalnya, input pengguna), atau jika Anda ingin menghindari banyak meta karakter, maka Anda mungkin sebaiknya menggunakan indexOfseperti ini:

matchString = 'best';
// If the match string is coming from user input you could do
// matchString = userInput.toLowerCase() here.

if (string.toLowerCase().indexOf(matchString) != -1){
    alert('Matched');
}
Dan
sumber
9
Maaf, bagaimana Anda bisa mengubah "terbaik" menjadi variabel dalam contoh pertama Anda? string.match(/best/i);
Doug Molineux
5
Mengapa Anda gunakan .matchuntuk perbandingan boolean. Itu mencari di luar hasil pertama. Anda harus berhenti setelah pertandingan pertama yang dilakukan .testatau .searchdilakukan. Periksa kinerja di sini .
Rami
toLowerCasekemungkinan besar akan gagal dalam Tes Turki ( moserware.com/2008/02/does-your-code-pass-turkey-test.html ) dan masalah konversi kasus serupa. Saya tidak yakin bagaimana ReGexmenanganinya, tetapi jika saya harus menebak saya akan mengatakan lebih baik.
Ohad Schneider
3
@ DougMolineux Anda dapat menggunakan konstruktor objek RegExp. var text = "best"; var exp = new RegExp(test, "i");. Ini sama dengan /best/i.
Medeni Baykal
174

Menggantikan

var result= string.search(/searchstring/i);

dengan

var result= string.search(new RegExp(searchstring, "i"));
Sergey Ilinsky
sumber
7
Itu cara yang agak berantakan di sekitarnya, karena diperlukan langkah-langkah untuk menjaga dari metakarakter regexp yang tidak terduga.
Dan
35
Dan, saya ragu jawaban saya layak -1 dari Anda. Saya mencoba membantu ChrisBo dengan memperbaiki penggunaan JavaScript yang tidak tepat, yaitu: var result = string.search (/ searchstring / i); ke yang tepat, di mana pencarian variabel digunakan sesuai keinginannya.
Sergey Ilinsky
8
Kanan Dan (meskipun ia mungkin bermaksud mengatakan " tidak ada ukuran"): s = 'a[b'; r = new RegExp(s)menghasilkan kesalahan sintaks (kelas karakter yang tidak dikuatkan)
glenn jackman
39

Jika Anda hanya mencari string daripada ekspresi reguler yang lebih rumit, Anda dapat menggunakan indexOf()- tapi ingat untuk huruf kecil kedua string terlebih dahulu karena indexOf()case-sensitive:

var string="Stackoverflow is the BEST"; 
var searchstring="best";

// lowercase both strings
var lcString=string.toLowerCase();
var lcSearchString=searchstring.toLowerCase();

var result = lcString.indexOf(lcSearchString)>=0;
alert(result);

Atau dalam satu baris:

var result = string.toLowerCase().indexOf(searchstring.toLowerCase())>=0;
Odilon Redo
sumber
24

Misalkan kita ingin menemukan variabel string needledalam variabel string haystack. Ada tiga gotcha:

  1. Aplikasi internasional harus menghindari string.toUpperCasedan string.toLowerCase. Gunakan ekspresi reguler yang mengabaikan huruf besar-kecil. Misalnya var needleRegExp = new RegExp(needle, "i");diikuti oleh needleRegExp.test(haystack).
  2. Secara umum, Anda mungkin tidak tahu nilai needle. Hati-hati agar needletidak mengandung ekspresi reguler karakter khusus . Lari ini menggunakan needle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");.
  3. Dalam kasus lain, jika Anda ingin mencocokkan secara tepat needledan haystack, hanya mengabaikan kasing, pastikan untuk menambahkan "^"di awal dan "$"di akhir konstruktor ekspresi reguler Anda.

Mempertimbangkan poin (1) dan (2), contohnya adalah:

var haystack = "A. BAIL. Of. Hay.";
var needle = "bail.";
var needleRegExp = new RegExp(needle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), "i");
var result = needleRegExp.test(haystack);
alert(result);
Chris Chute
sumber
4

ES6 +:

let string="Stackoverflow is the BEST";
let searchstring="best";


let found = string.toLowerCase()
                  .includes(searchstring.toLowerCase());

includes()kembali truejika searchStringmuncul di satu posisi atau lebih atau falsesebaliknya.

Andrey
sumber
2

Jika Anda khawatir tentang kasus "kelas karakter yang tidak ditentukan", menghapus semua karakter non-alfanumerik akan membantu:

searchstring = searchstring.replace (/ [^ a-zA-Z 0-9] + / g, '');
dsomnus
sumber
2

Saya suka jawaban @ CHR15TO, tidak seperti jawaban lain yang pernah saya lihat pada pertanyaan serupa lainnya, jawaban itu benar-benar menunjukkan bagaimana cara keluar dengan benar dari string pencarian yang disediakan oleh pengguna (daripada mengatakan itu perlu tanpa menunjukkan bagaimana).

Namun, itu masih cukup kikuk, dan mungkin relatif lebih lambat. Jadi mengapa tidak memiliki solusi spesifik untuk apa yang mungkin merupakan persyaratan umum untuk coders? (Dan mengapa tidak memasukkannya ke ES6 API BTW?)

Jawaban saya [ https://stackoverflow.com/a/38290557/887092] pada pertanyaan serupa memungkinkan yang berikut:

var haystack = 'A. BAIL. Of. Hay.';
var needle = 'bail.';
var index = haystack.naturalIndexOf(needle);
Todd
sumber
1

Ada dua cara untuk perbandingan kasus sensitif:

  1. Konversikan string ke huruf besar dan kemudian bandingkan dengan menggunakan operator ketat ( ===). Cara ketat operator memperlakukan operan membaca hal-hal di: http://www.thesstech.com/javascript/relational-logical-operators

  2. Pencocokan pola menggunakan metode string:

    Gunakan metode string "pencarian" untuk pencarian case-sensitive. Baca tentang pencarian dan metode string lainnya 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>
Sohail Arif
sumber
1

Saya sering melakukan ini dan menggunakan prototipe 5 garis sederhana yang menerima varargs. Ini cepat dan bekerja di mana-mana .

myString.containsIgnoreCase('red','orange','yellow')

/**
 * @param {...string} var_strings Strings to search for
 * @return {boolean} true if ANY of the arguments is contained in the string
 */
String.prototype.containsIgnoreCase = function(var_strings) {
  const thisLowerCase = this.toLowerCase()
  for (let i = 0; i < arguments.length; i++) {
    let needle = arguments[i]
    if (thisLowerCase.indexOf(needle.toLowerCase()) >= 0) {
      return true
    }
  }
  return false
}

/**
 * @param {...string} var_strings Strings to search for
 * @return {boolean} true if ALL of the arguments are contained in the string
 */
String.prototype.containsAllIgnoreCase = function(var_strings) {
  const thisLowerCase = this.toLowerCase()
  for (let i = 0; i < arguments.length; i++) {
    let needle = arguments[i]
    if (thisLowerCase.indexOf(needle.toLowerCase()) === -1) {
      return false
    }
  }
  return true
}

// Unit test

let content = `
FIRST SECOND
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
FOO BAR
`

let data = [
  'foo',
  'Foo',
  'foobar',
  'barfoo',
  'first',
  'second'
]

let result
data.forEach(item => {
  console.log('Searching for', item)
  result = content.containsIgnoreCase(item)
  console.log(result ? 'Found' : 'Not Found')
})

console.log('Searching for', 'x, y, foo')
result = content.containsIgnoreCase('x', 'y', 'foo');
console.log(result ? 'Found' : 'Not Found')

console.log('Searching for all', 'foo, bar, foobar')
result = content.containsAllIgnoreCase('foo', 'bar', 'foobar');
console.log(result ? 'Found' : 'Not Found')

console.log('Searching for all', 'foo, bar')
result = content.containsAllIgnoreCase('foo', 'bar');
console.log(result ? 'Found' : 'Not Found')

Steven Spungin
sumber
0

Anda bisa membuat semuanya huruf kecil:

var string="Stackoverflow is the BEST";
var searchstring="best";
var result= (string.toLowerCase()).search((searchstring.toLowerCase()));
alert(result);
Robbert
sumber
-1

Saya perhatikan bahwa jika pengguna memasukkan string teks tetapi meninggalkan input tanpa memilih opsi autocomplete, tidak ada nilai yang ditetapkan dalam input tersembunyi, bahkan jika string bertepatan dengan satu di array. Jadi, dengan bantuan jawaban lain saya membuat ini:

var $local_source = [{
        value: 1,
        label: "c++"
    }, {
        value: 2,
        label: "java"
    }, {
        value: 3,
        label: "php"
    }, {
        value: 4,
        label: "coldfusion"
    }, {
        value: 5,
        label: "javascript"
    }, {
        value: 6,
        label: "asp"
    }, {
        value: 7,
        label: "ruby"
    }];
    $('#search-fld').autocomplete({
        source: $local_source,
        select: function (event, ui) {
            $("#search-fld").val(ui.item.label); // display the selected text
            $("#search-fldID").val(ui.item.value); // save selected id to hidden input
            return false;
        },
        change: function( event, ui ) {

            var isInArray = false;

            $local_source.forEach(function(element, index){

                if ($("#search-fld").val().toUpperCase() == element.label.toUpperCase()) {
                    isInArray = true;
                    $("#search-fld").val(element.label); // display the selected text
                    $("#search-fldID").val(element.value); // save selected id to hidden input
                    console.log('inarray: '+isInArray+' label: '+element.label+' value: '+element.value);
                };

            });

            if(!isInArray){

                $("#search-fld").val(''); // display the selected text
                $( "#search-fldID" ).val( ui.item? ui.item.value : 0 );

            }
        } 
Lalu
sumber