Tìm kiếm không phân biệt chữ hoa chữ thường


272

Tôi đang cố gắng để có được một tìm kiếm không phân biệt chữ hoa chữ thường với hai chuỗi trong JavaScript hoạt động.

Thông thường nó sẽ như thế này:

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

Các /ilá cờ sẽ cho case-insensitive.

Nhưng tôi cần tìm kiếm một chuỗi thứ hai; không có cờ nó hoạt động hoàn hảo:

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

Nếu tôi thêm /icờ vào ví dụ trên, nó sẽ tìm kiếm chuỗi tìm kiếm và không tìm kiếm trong biến "chuỗi tìm kiếm" (ví dụ tiếp theo không hoạt động):

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

Làm thế nào tôi có thể đạt được điều này?

Câu trả lời:


373

Vâng, sử dụng .match, chứ không phải .search. Kết quả từ .matchcuộc gọi sẽ trả về chuỗi thực tế được khớp với chính nó, nhưng nó vẫn có thể được sử dụng làm giá trị boolean.

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

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

Sử dụng một biểu thức chính quy như thế có lẽ là cách rõ ràng nhất và rõ ràng nhất để làm điều đó trong JavaScript, nhưng hãy nhớ rằng đó một biểu thức chính quy và do đó có thể chứa các siêu ký tự regex. Nếu bạn muốn lấy chuỗi từ nơi khác (ví dụ: đầu vào của người dùng) hoặc nếu bạn muốn tránh phải thoát nhiều ký tự đại diện, thì có lẽ bạn nên sử dụng tốt nhất indexOfnhư thế này:

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');
}

9
Xin lỗi, làm thế nào bạn có thể chuyển đổi "tốt nhất" thành một biến trong ví dụ đầu tiên của bạn? string.match(/best/i);
Doug Molineux

5
Tại sao bạn sẽ sử dụng .matchđể so sánh boolean. Nó tìm kiếm ngoài kết quả đầu tiên. Bạn cần dừng lại sau trận đấu đầu tiên .testhoặc .searchlàm. Kiểm tra hiệu suất ở đây .
Rami

toLowerCaserất có thể sẽ thất bại trong Bài kiểm tra Thổ Nhĩ Kỳ ( moserware.com/2008/02/does-your-code-pass-turkey-test.html ) và các vấn đề chuyển đổi trường hợp tương tự. Tôi không chắc làm thế nào để ReGexxử lý nó, nhưng nếu tôi phải đoán tôi sẽ nói tốt hơn.
Ohad Schneider

3
@DougMolineux bạn có thể sử dụng hàm tạo đối tượng RegExp. var text = "best"; var exp = new RegExp(test, "i");. Điều này cũng giống như /best/i.
Medeni Baykal

174

Thay thế

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

với

var result= string.search(new RegExp(searchstring, "i"));

7
Đó là một cách khá lộn xộn xung quanh nó, vì nó cần các biện pháp để bảo vệ chống lại các siêu nhân vật phản ứng bất ngờ.
Dan

35
Dan, tôi nghi ngờ câu trả lời của tôi xứng đáng -1 từ bạn. Tôi đã cố gắng giúp ChrisBo bằng cách sửa lỗi sử dụng JavaScript không đúng của anh ấy, cụ thể là: var result = string.search (/ searchopes / i); đến một cái thích hợp, trong đó chuỗi tìm kiếm biến được sử dụng theo cách anh ta dự định.
Serge Ilinsky

8
Dan đúng (mặc dù anh ta có thể có ý nói " không có biện pháp"): s = 'a[b'; r = new RegExp(s)dẫn đến lỗi cú pháp (lớp ký tự bị hủy)
glenn jackman

39

Nếu bạn chỉ tìm kiếm một chuỗi chứ không phải là một biểu thức thông thường phức tạp hơn, bạn có thể sử dụng indexOf()- nhưng hãy nhớ viết thường cả hai chuỗi trước vì phân biệt chữ hoa chữ thường indexOf():

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);

Hoặc trong một dòng duy nhất:

var result = string.toLowerCase().indexOf(searchstring.toLowerCase())>=0;

24

Giả sử chúng ta muốn tìm biến chuỗi needletrong biến chuỗi haystack. Có ba vấn đề:

  1. Các ứng dụng quốc tế nên tránh string.toUpperCasestring.toLowerCase. Sử dụng một biểu thức thông thường mà bỏ qua trường hợp thay thế. Ví dụ, var needleRegExp = new RegExp(needle, "i");theo sau needleRegExp.test(haystack).
  2. Nói chung, bạn có thể không biết giá trị của needle. Hãy cẩn thận needlekhông chứa bất kỳ ký tự đặc biệt biểu thức chính quy . Thoát khỏi những bằng cách sử dụng needle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");.
  3. Trong các trường hợp khác, nếu bạn muốn khớp chính xác needlehaystack, chỉ cần bỏ qua trường hợp, hãy đảm bảo thêm "^"vào lúc bắt đầu và "$"ở cuối hàm tạo biểu thức chính quy của bạn.

Cân nhắc các điểm (1) và (2), một ví dụ sẽ là:

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);

4

ES6 +:

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


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

includes()trả về truenếu searchStringxuất hiện ở một hoặc nhiều vị trí falsekhác.


2

Nếu bạn lo lắng về trường hợp "lớp ký tự bị hủy bỏ", loại bỏ tất cả các ký tự không chữ và số sẽ hữu ích:

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

2

Tôi thích câu trả lời của @ CHR15TO, không giống như các câu trả lời khác mà tôi đã thấy đối với các câu hỏi tương tự khác, câu trả lời đó thực sự cho thấy cách thoát đúng chuỗi tìm kiếm do người dùng cung cấp (thay vì nói nó sẽ cần thiết mà không hiển thị như thế nào).

Tuy nhiên, nó vẫn còn khá lộn xộn và có thể tương đối chậm hơn. Vậy tại sao không có một giải pháp cụ thể cho những gì có khả năng là một yêu cầu chung cho các lập trình viên? (Và tại sao không đưa nó vào API ES6 của ES6?)

Câu trả lời của tôi [ https://stackoverflow.com/a/38290557/887092] cho một câu hỏi tương tự cho phép như sau:

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

1

Có hai cách để so sánh trường hợp không nhạy cảm:

  1. Chuyển đổi chuỗi thành chữ hoa và sau đó so sánh chúng bằng toán tử nghiêm ngặt ( ===). Cách toán tử nghiêm ngặt xử lý toán hạng đọc công cụ tại: http://www.thesstech.com/javascript/relational-logical-operators

  2. Khớp mẫu bằng các phương thức chuỗi:

    Sử dụng phương pháp chuỗi "tìm kiếm" cho tìm kiếm không phân biệt chữ hoa chữ thường. Đọc về tìm kiếm và các phương thức chuỗi khác tại: http://www.thesstech.com/potype-matching-USE-opes-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>

1

Tôi làm điều này thường xuyên và sử dụng một nguyên mẫu 5 dòng đơn giản chấp nhận varargs. Nó là nhanh chóng và làm việc ở khắp mọi nơi .

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')


0

Bạn có thể làm mọi thứ viết thường:

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

-1

Tôi nhận thấy rằng nếu người dùng nhập một chuỗi văn bản nhưng để lại đầu vào mà không chọn bất kỳ tùy chọn tự động hoàn thành nào thì không có giá trị nào được đặt trong đầu vào ẩn, ngay cả khi chuỗi trùng với một trong mảng. Vì vậy, với sự giúp đỡ của các câu trả lời khác, tôi đã thực hiện điều này:

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 );

            }
        } 
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.