Chứa trường hợp không nhạy cảm


413

Tôi có những điều sau đây:

if (referrer.indexOf("Ral") == -1) { ... }

Những gì tôi muốn làm là làm cho Raltrường hợp nhạy cảm, do đó nó có thể được RAl, rAl, vv và vẫn phù hợp.

Có cách nào để nói rằng Ralphải không phân biệt chữ hoa chữ thường?


3
Tôi nghĩ rằng regex không nhạy cảm trường hợp là giải pháp thanh lịch hơn nhưng mọi người nên ghi nhớ những cạm bẫy của việc tạo RegExptrực tiếp từ đầu vào của người dùng. Ví dụ: người dùng có thể nhập *và một lỗi sẽ được đưa vào hàm RegExptạo. Các giải pháp được chấp nhận không có vấn đề này.
vui mừng

Câu trả lời:


604

Thêm .toLowerCase()sau referrer. Phương thức này biến chuỗi trong một chuỗi chữ thường. Sau đó, sử dụng sử .indexOf()dụng ralthay vì Ral.

if (referrer.toLowerCase().indexOf("ral") === -1) { 

Điều tương tự cũng có thể đạt được bằng cách sử dụng Biểu thức chính quy (đặc biệt hữu ích khi bạn muốn kiểm tra các mẫu động):

if (!/Ral/i.test(referrer)) {
   //    ^i = Ignore case flag for RegExp

16
Phương pháp sau đúng hơn; cái trước sẽ thất bại đối với I Thổ Nhĩ Kỳ và bất kỳ cặp chữ hoa / chữ thường có vấn đề nào khác: i18nguy.com/unicode/turkish-i18n.html
Domenic

23
Đối với Thổ Nhĩ Kỳ, sẽ tốt hơn nếu sử dụng toLocaleLowerCase()( ref )
Mottie

2
câu hỏi sau không trả lời câu hỏi, nó chỉ nói nếu nó ở đó, không lấy chỉ số của trận đấu. Hoặc tiêu đề câu hỏi là sai, hoặc câu hỏi.
Maslow

10
@Maslow Ví dụ về câu hỏi là về sự vô cảm của trường hợp thử nghiệm. Nếu bạn muốn lấy chỉ mục, hãy sử dụng phương thức của String.search :var index = referrer.search(/Ral/i);
Rob W

7
Sự phức tạp thêm vào của cách tiếp cận Biểu thức chính quy động là nếu chuỗi tìm kiếm, ví dụ "Ral", có chứa các ký tự đặc biệt Biểu thức chính quy, chẳng hạn như $. *? v.v., bạn sẽ gặp vấn đề, vì vậy bạn sẽ cần phải thoát khỏi các ký tự đặc biệt, xem câu trả lời của Mike Samuel trên bài đăng này: kết thúc với JavaScript
zachelrath

94

Một tùy chọn khác là sử dụng phương pháp tìm kiếm như sau:

if (referrer.search(new RegExp("Ral", "i")) == -1) { ...

Nó trông thanh lịch hơn sau đó chuyển đổi toàn bộ chuỗi thành chữ thường và nó có thể hiệu quả hơn.
Với toLowerCase()mã có hai lần vượt qua chuỗi, một lần vượt qua trên toàn bộ chuỗi để chuyển đổi nó thành chữ thường và cách khác là tìm kiếm chỉ mục mong muốn.
Với RegExpmã có một lần vượt qua chuỗi mà nó trông phù hợp với chỉ mục mong muốn.

Do đó, trên các chuỗi dài tôi khuyên bạn nên sử dụng RegExpphiên bản (tôi đoán rằng trên các chuỗi ngắn, hiệu quả này xuất phát từ tài khoản tạo RegExpđối tượng mặc dù)


2
Điều này cũng nhanh hơn một chút dựa trên các thử nghiệm của tôi: jsperf.com/case-insensitive-indexof
Ilan Biala

6
Kể từ 2018.10.24, toLowerCase giành chiến thắng với tỷ suất lợi nhuận lớn trong Chrome. toLowerCase (95,914,378 - ± 0,89% - nhanh nhất), regex indexOf (269.307 - ± 0,87% chậm hơn 100%)
nixkuroi

21

Sử dụng RegExp:

if (!/ral/i.test(referrer)) {
    ...
}

Hoặc, sử dụng .toLowerCase():

if (referrer.toLowerCase().indexOf("ral") == -1)

1
+1, điều này có khả năng có thể đúng hơn bằng cách tránh "vấn đề I của Thổ Nhĩ Kỳ" và những cạm bẫy khác: i18nguy.com/unicode/turkish-i18n.html
Domenic

15

Từ ES2016, bạn cũng có thể sử dụng phương pháp tốt hơn / dễ dàng hơn / thanh lịch hơn một chút (phân biệt chữ hoa chữ thường):

if (referrer.includes("Ral")) { ... }

hoặc (không phân biệt chữ hoa chữ thường):

if (referrer.toLowerCase().includes(someString.toLowerCase())) { ... }

Dưới đây là một số so sánh .indexOf().includes(): https://dev.to/adroitcoder/includes-vs-indexof-in-javascript


1
Tôi không nghĩ bao gồm trường hợp không nhạy cảm
Kyle s

4
@Kyles includestrường hợp nhạy cảm trong Chrome: thử 'fooBar'.includes('bar')==>false
drzaus

10

Có một vài cách tiếp cận ở đây.

Nếu bạn muốn thực hiện kiểm tra không phân biệt chữ hoa chữ thường cho trường hợp này, hãy làm một cái gì đó như sau.

if (referrer.toLowerCase().indexOf("Ral".toLowerCase()) == -1) {
    ...

Ngoài ra, nếu bạn đang thực hiện kiểm tra này thường xuyên, bạn có thể thêm một indexOf()phương thức giống như mới String, nhưng làm cho nó không nhạy cảm.

String.prototype.indexOfInsensitive = function (s, b) {
    return this.toLowerCase().indexOf(s.toLowerCase(), b);
}

// Then invoke it
if (referrer.indexOfInsensitive("Ral") == -1) { ...

1
Đối với các trình duyệt hiện đại hỗ trợ defineProperty, tôi đề nghị Object.defineProperty(String.prototype, 'indexOfInsensitive', {value: function(s,b){return this.toLowerCase().indexOf((s+'').toLowerCase(),b);}});. Hai bản cập nhật: Chuyển đổi chuỗi rõ ràng bằng cách sử dụng (s+'')và không thể đếm được trong một vòng lặp ( for(var i in '') ... không hiển thị indexOfInsensitive.
Rob W

5
if (referrer.toUpperCase().indexOf("RAL") == -1) { ...

@Domenic: Với tất cả sự tôn trọng đối với văn hóa Thổ Nhĩ Kỳ, Thổ Nhĩ Kỳ nên xem xét cải cách chính tả để đơn giản hóa khía cạnh này. Trung Quốc đã có một số cải cách đơn giản hóa , và Thổ Nhĩ Kỳ có ít hơn 10% dân số Trung Quốc, và một bảng chữ cái đơn giản hơn nhiều. Nó có thể được thực hiện.
Dan Dascalescu


3

Ví dụ cho bất kỳ ngôn ngữ:

'My name is Хведор'.toLocaleLowerCase().includes('ХвЕдОр'.toLocaleLowerCase())

2

Đó là năm 2016, và không có cách rõ ràng để làm điều này? Tôi đã hy vọng cho một số copypasta. Tôi sẽ đi

Ghi chú thiết kế: Tôi muốn giảm thiểu việc sử dụng bộ nhớ và do đó cải thiện tốc độ - vì vậy không có sự sao chép / biến đổi chuỗi. Tôi giả sử V8 (và các động cơ khác) có thể tối ưu hóa chức năng này.

//TODO: Performance testing
String.prototype.naturalIndexOf = function(needle) {
    //TODO: guard conditions here

    var haystack = this; //You can replace `haystack` for `this` below but I wan't to make the algorithm more readable for the answer
    var needleIndex = 0;
    var foundAt = 0;
    for (var haystackIndex = 0; haystackIndex < haystack.length; haystackIndex++) {
        var needleCode = needle.charCodeAt(needleIndex);
        if (needleCode >= 65 && needleCode <= 90) needleCode += 32; //ToLower. I could have made this a function, but hopefully inline is faster and terser
        var haystackCode = haystack.charCodeAt(haystackIndex);
        if (haystackCode >= 65 && haystackCode <= 90) haystackCode += 32; //ToLower. I could have made this a function, but hopefully inline is faster and terser

        //TODO: code to detect unicode characters and fallback to toLowerCase - when > 128?
        //if (needleCode > 128 || haystackCode > 128) return haystack.toLocaleLowerCase().indexOf(needle.toLocaleLowerCase();
        if (haystackCode !== needleCode)
        {
            foundAt = haystackIndex;
            needleIndex = 0; //Start again
        }
        else
            needleIndex++;

        if (needleIndex == needle.length)
            return foundAt;
    }

    return -1;
}

Lý do của tôi cho tên:

  • Nên có IndexOf trong tên
  • Không thêm hậu tố - Tham chiếu đến tham số sau
  • Đừng sử dụng "caseInsensitive" quá lâu
  • "Tự nhiên" là một ứng cử viên tốt, bởi vì so sánh trường hợp nhạy cảm mặc định không phải là tự nhiên đối với con người ở nơi đầu tiên.

Tại sao không...:

  • toLowerCase() - các cuộc gọi lặp lại tiềm năng tới toLowerCase trên cùng một chuỗi.
  • RegExp- lúng túng khi tìm kiếm với biến. Ngay cả đối tượng RegExp cũng lúng túng khi phải thoát các ký tự

2
Đó là năm 2016, và bạn vẫn nghĩ rằng tiếng Anh (hoặc các ngôn ngữ chỉ ASCII khác) là ngôn ngữ duy nhất trên thế giới?
Roland Illig

3
@RolandIllig Ouch. Câu trả lời của tôi không phù hợp với các nền văn hóa khác, đó là một nhược điểm. Tôi sẽ hoan nghênh mọi hiểu biết sâu sắc về việc hỗ trợ mở rộng cho nhiều nền văn hóa hơn, thế giới là một nơi tốt hơn với các cộng tác viên.
Todd

1

Để thực hiện tìm kiếm tốt hơn, sử dụng mã sau đây,

var myFav   = "javascript";
var theList = "VB.NET, C#, PHP, Python, JavaScript, and Ruby";

// Check for matches with the plain vanilla indexOf() method:
alert( theList.indexOf( myFav ) );

// Now check for matches in lower-cased strings:
alert( theList.toLowerCase().indexOf( myFav.toLowerCase() ) );

Trong cảnh báo đầu tiên (), JavaScript trả về "-1" - nói cách khác, indexOf () không tìm thấy kết quả khớp: điều này đơn giản là vì "JavaScript" được viết thường trong chuỗi đầu tiên và được viết hoa đúng trong chuỗi thứ hai. Để thực hiện tìm kiếm không phân biệt chữ hoa chữ thường với indexOf (), bạn có thể tạo cả hai chuỗi bằng chữ hoa hoặc chữ thường. Điều này có nghĩa là, như trong cảnh báo thứ hai (), JavaScript sẽ chỉ kiểm tra sự xuất hiện của chuỗi bạn đang tìm kiếm, viết hoa bị bỏ qua.

Tham khảo, http://freewebdesigntutorials.com/javaScriptTutorials/jsStringObject/indexOfMethod.htmlm


1

Nếu referrerlà một mảng, bạn có thể sử dụngfindIndex()

 if(referrer.findIndex(item => 'ral' === item.toLowerCase()) == -1) {...}

0

Đây là của tôi:

Kịch bản :

var originalText = $("#textContainer").html()
$("#search").on('keyup', function () {
  $("#textContainer").html(originalText)
  var text = $("#textContainer").html()
  var val = $("#search").val()
  if(val=="") return;
  var matches = text.split(val)
  for(var i=0;i<matches.length-1;i++) {
    var ind =  matches[i].indexOf(val)
    var len = val.length
      matches[i] = matches[i] + "<span class='selected'>" + val + "</span>"
  }
  $("#textContainer").html(matches.join(""))

HTML:

<input type="text" id="search">
<div id="textContainer">
lorem ipsum is simply dummy text of the printing and typesetting industry. lorem ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of letraset sheets containing lorem ipsum passages, and more recently with desktop publishing software like Aldus pagemaker including versions of lorem ipsum.</div>

Codepen

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.