มีตัวพิมพ์เล็กและตัวพิมพ์ใหญ่


413

ฉันมีดังต่อไปนี้:

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

สิ่งที่ฉันต้องการจะทำคือการทำให้Ralกรณีตายเพื่อที่จะสามารถRAl, rAlฯลฯ และยังคงแข่งขัน

มีวิธีที่จะพูดแบบนั้นRalหรือไม่?


3
ฉันคิดว่า case insensitive regex เป็นโซลูชันที่หรูหรากว่า แต่ทุกคนควรระลึกถึงข้อผิดพลาดในการสร้างRegExpโดยตรงจากอินพุตของผู้ใช้ ตัวอย่างเช่นผู้ใช้สามารถป้อน*และข้อผิดพลาดจะถูกโยนลงในตัวRegExpสร้าง วิธีแก้ไขปัญหาที่ยอมรับไม่มีปัญหานี้
pllee

คำตอบ:


604

เพิ่มหลัง.toLowerCase() referrerวิธีนี้เปลี่ยนสตริงเป็นสตริงตัวพิมพ์เล็ก จากนั้นใช้.indexOf()ใช้แทนralRal

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

สามารถทำได้เช่นเดียวกันโดยใช้นิพจน์ปกติ (มีประโยชน์อย่างยิ่งเมื่อคุณต้องการทดสอบกับรูปแบบไดนามิก):

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

16
วิธีหลังมีความถูกต้องมากขึ้น อดีตจะล้มเหลวสำหรับตุรกี I และคู่อื่น ๆ ที่เป็นตัวพิมพ์ใหญ่ / ตัวพิมพ์เล็กที่มีปัญหาเช่น: i18nguy.com/unicode/turkish-i18n.html
Domenic

23
สำหรับภาษาตุรกีจะดีกว่าที่จะใช้toLocaleLowerCase()( อ้างอิง )
Mottie

2
หลังไม่ตอบคำถามมันบอกแค่ว่ามันอยู่ที่นั่นไม่ได้ดัชนีของการแข่งขัน อาจเป็นชื่อคำถามที่ผิดหรือคำถาม
Maslow

10
@Maslow ตัวอย่างของคำถามเกี่ยวกับการทดสอบการไม่สนใจขนาดตัวพิมพ์ หากคุณต้องการที่จะได้รับดัชนีใช้String ของ.searchวิธีการ:var index = referrer.search(/Ral/i);
ร็อบ W

7
ความซับซ้อนที่เพิ่มขึ้นของวิธีการนิพจน์ปกติแบบไดนามิกคือถ้าสตริงการค้นหาเช่น "Ral" มีอักขระพิเศษของนิพจน์ปกติเช่น $. *? ฯลฯ คุณจะมีปัญหาดังนั้นคุณจะต้องหลบหนีจากตัวละครพิเศษดูคำตอบของ Mike Samuel ในโพสต์นี้: ลงท้ายด้วย JavaScript
zachelrath

94

ตัวเลือกอื่นคือใช้วิธีการค้นหาดังนี้:

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

มันดูหรูหรามากขึ้นแล้วแปลงสตริงทั้งหมดเป็นตัวพิมพ์เล็กและอาจมีประสิทธิภาพมากกว่า
ด้วยtoLowerCase()รหัสที่มีสองผ่านสายสตริงหนึ่งผ่านอยู่บนสตริงทั้งหมดเพื่อแปลงเป็นตัวพิมพ์เล็กและอีกคือการค้นหาดัชนีที่ต้องการ
ด้วยRegExpรหัสที่มีหนึ่งผ่านสายซึ่งดูเหมือนว่าจะตรงกับดัชนีที่ต้องการ

ดังนั้นในสายยาวฉันแนะนำให้ใช้RegExpรุ่น (ฉันเดาว่าในสายสั้นประสิทธิภาพนี้มาในบัญชีของการสร้างRegExpวัตถุแม้ว่า)


2
นี่ยังค่อนข้างเร็วขึ้นอยู่กับการทดสอบของฉัน: jsperf.com/case-insensitive-indexof
Ilan Biala

6
ตั้งแต่ 2018.10.24 toLowerCase ชนะโดยกำไรจำนวนมากใน Chrome toLowerCase (95,914,378 - ± 0.89% - เร็วที่สุด), ดัชนี regexO (269,307 - ± 0.87% ช้าลง 100%)
nixkuroi

21

ใช้ RegExp:

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

หรือใช้.toLowerCase():

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

1
+1 สิ่งนี้อาจแก้ไขได้มากขึ้นโดยการหลีกเลี่ยง "ปัญหาตุรกีฉัน" และข้อผิดพลาดอื่น ๆ : i18nguy.com/unicode/turkish-i18n.html
Domenic

15

จาก ES2016 คุณยังสามารถใช้วิธีที่ดีขึ้นเล็กน้อย / ง่ายขึ้น / หรูหรามากขึ้น (เล็ก - ใหญ่):

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

หรือ (ไม่คำนึงถึงขนาดตัวพิมพ์):

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

นี่คือการเปรียบเทียบ.indexOf()และ.includes(): https://dev.to/adroitcoder/includes-vs-indexof-in-javascript


1
ฉันไม่คิดว่าจะรวมถึงตัวพิมพ์เล็กและใหญ่
Kyle s

4
@Kyles includesเป็นกรณี ๆ ไปใน Chrome: ลอง'fooBar'.includes('bar')==>false
drzaus

10

มีสองวิธีที่นี่

หากคุณต้องการตรวจสอบแบบตัวเล็กและตัวเล็กสำหรับอินสแตนซ์นี้ให้ทำสิ่งต่อไปนี้

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

หรือหากคุณดำเนินการตรวจสอบนี้เป็นประจำคุณสามารถเพิ่มindexOf()วิธีที่เหมือนใหม่ได้Stringแต่ทำให้ไม่ต้องสนใจขนาดตัวพิมพ์

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

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

1
เบราว์เซอร์ที่ทันสมัยที่สนับสนุนผมขอแนะนำให้defineProperty Object.defineProperty(String.prototype, 'indexOfInsensitive', {value: function(s,b){return this.toLowerCase().indexOf((s+'').toLowerCase(),b);}});การอัปเดตสองรายการ: การแปลงสตริงอย่างชัดเจนโดยใช้(s+'')และไม่นับในลูป ( for(var i in '') ... ไม่แสดงindexOfInsensitive)
Rob W

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

@Domenic: ด้วยความเคารพอย่างยิ่งต่อวัฒนธรรมตุรกีตุรกีควรพิจารณาการปฏิรูปการสะกดคำเพื่อทำให้มุมมองนี้ง่ายขึ้น จีนมีการปฏิรูปอย่างง่ายจำนวนมากและตุรกีมีประชากรน้อยกว่า 10% ของจีนและมีตัวอักษรที่เรียบง่ายกว่ามาก มันสามารถทำได้
Dan Dascalescu



2

ปี 2559 และไม่มีวิธีที่ชัดเจนในการทำเช่นนี้? ฉันหวังว่าจะได้ copypasta ฉันจะไป

บันทึกการออกแบบ: ฉันต้องการลดการใช้หน่วยความจำให้น้อยที่สุดและปรับปรุงความเร็ว - ดังนั้นจึงไม่มีการคัดลอก / การกลายพันธุ์ของสตริง ฉันถือว่า V8 (และเอ็นจิ้นอื่น ๆ ) สามารถปรับฟังก์ชั่นนี้ได้

//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;
}

เหตุผลของฉันสำหรับชื่อ:

  • ควรมี IndexOf ในชื่อ
  • อย่าเพิ่มคำต่อท้าย - หมายถึงพารามิเตอร์ต่อไปนี้
  • อย่าใช้ "ตัวพิมพ์เล็กและใหญ่" ที่ยาวมาก
  • "ธรรมชาติ" เป็นตัวเลือกที่ดีเนื่องจากการเปรียบเทียบแบบตัวพิมพ์เล็กและตัวพิมพ์ใหญ่นั้นไม่ได้เป็นไปตามธรรมชาติตั้งแต่แรก

ทำไมจะไม่ล่ะ...:

  • toLowerCase() - การเรียกซ้ำไปยัง toLowerCase ซ้ำบนสายอักขระเดียวกัน
  • RegExp- อึดอัดในการค้นหาด้วยตัวแปร แม้แต่วัตถุ RegExp ก็ยังอึดอัดที่จะต้องหลบหนีจากตัวละคร

2
ปี 2559 และคุณยังคิดว่าภาษาอังกฤษ (หรือภาษาอื่น ๆ ของ ASCII เท่านั้น) เป็นภาษาเดียวในโลก?
Roland Illig

3
@RolandIllig Ouch คำตอบของฉันไม่รองรับวัฒนธรรมอื่น ๆ นั่นคือข้อเสียเปรียบ ฉันยินดีรับข้อมูลเชิงลึกเกี่ยวกับการสนับสนุนที่กว้างขึ้นสำหรับวัฒนธรรมที่มากขึ้นโลกเป็นที่ที่ดีกว่าสำหรับผู้ทำงานร่วมกัน
ทอดด์

1

หากต้องการทำการค้นหาที่ดีขึ้นให้ใช้รหัสต่อไปนี้

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

ในการแจ้งเตือนครั้งแรก () JavaScript ส่งคืน "-1" - กล่าวอีกนัยหนึ่ง indexOf () ไม่พบรายการที่ตรงกัน: นี่เป็นเพียงเพราะ "JavaScript" เป็นตัวพิมพ์เล็กในสตริงแรกและพิมพ์ตัวพิมพ์ใหญ่อย่างถูกต้องในสอง ในการค้นหาด้วยตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ด้วย indexOf () คุณสามารถสร้างทั้งสองสตริงได้ทั้งตัวพิมพ์ใหญ่หรือตัวพิมพ์เล็ก ซึ่งหมายความว่าในการแจ้งเตือนครั้งที่สอง () JavaScript จะตรวจสอบเฉพาะการเกิดขึ้นของสตริงที่คุณต้องการการใช้อักษรตัวพิมพ์ใหญ่จะถูกละเว้น

การอ้างอิง http://freewebdesigntutorials.com/javaScriptTutorials/jsStringObject/indexOfMethod.htm


1

ถ้าreferrerเป็นอาร์เรย์คุณสามารถใช้findIndex()

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

0

นี่คือของฉัน:

สคริปต์ :

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.