การค้นหาแบบคำนึงถึงขนาดตัวพิมพ์


272

ฉันพยายามค้นหาตัวพิมพ์เล็กและใหญ่ด้วยสตริงสองตัวใน JavaScript ที่ใช้งานได้

โดยปกติมันจะเป็นเช่นนี้:

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

/iธงจะเป็นกรณีตาย

แต่ฉันต้องการค้นหาสตริงที่สอง หากไม่มีการตั้งค่าสถานะมันสมบูรณ์แบบ:

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

ถ้าฉันเพิ่มการ/iตั้งค่าสถานะไปที่ตัวอย่างข้างต้นมันจะค้นหา searchstring และไม่ใช่สิ่งที่อยู่ในตัวแปร "searchstring" (ตัวอย่างถัดไปไม่ทำงาน):

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

ฉันจะบรรลุสิ่งนี้ได้อย่างไร

คำตอบ:


373

ใช่ใช้มากกว่า.match .searchผลลัพธ์จากการ.matchโทรจะส่งคืนสตริงจริงที่จับคู่ตัวเอง แต่ก็ยังสามารถใช้เป็นค่าบูลีนได้

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

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

การใช้นิพจน์ทั่วไปเช่นนั้นน่าจะเป็นวิธีที่ง่ายที่สุดและชัดเจนที่สุดใน JavaScript แต่โปรดจำไว้ว่ามันเป็นนิพจน์ทั่วไปและอาจมีเมตาบอเรกของ regex หากคุณต้องการนำสตริงมาจากที่อื่น (เช่นอินพุตของผู้ใช้) หรือหากคุณต้องการหลีกเลี่ยงเมตาอักขระจำนวนมากคุณอาจใช้วิธีindexOfนี้ได้ดีที่สุด:

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
ขออภัยคุณจะแปลง "ดีที่สุด" เป็นตัวแปรในตัวอย่างแรกได้อย่างไร string.match(/best/i);
Doug Molineux

5
ทำไมคุณถึงใช้.matchสำหรับการเปรียบเทียบแบบบูล มันค้นหาเกินกว่าผลลัพธ์แรก คุณต้องหยุดหลังจากการแข่งขันครั้งแรก.testหรือ.searchไม่ ตรวจสอบประสิทธิภาพการทำงานที่นี่
Rami

toLowerCaseส่วนใหญ่จะล้มเหลวในการทดสอบตุรกี ( moserware.com/2008/02/does-your-code-pass-turkey-test.html ) และปัญหาการแปลงกรณีที่คล้ายกัน ฉันไม่แน่ใจว่าReGexจะจัดการอย่างไรแต่ถ้าฉันต้องเดาฉันจะพูดได้ดีกว่า
Ohad Schneider

3
@DougMolineux คุณสามารถใช้ตัวสร้างวัตถุ RegExp var text = "best"; var exp = new RegExp(test, "i");. /best/iนี้เป็นเช่นเดียวกับ
Medeni Baykal

174

แทนที่

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

กับ

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

7
นั่นเป็นวิธีที่ยุ่งเหยิงรอบ ๆ มันเนื่องจากต้องใช้มาตรการในการป้องกัน metacharacters regexp ที่ไม่คาดคิด
ด่าน

35
แดนฉันสงสัยคำตอบของฉันสมควรได้รับ -1 จากคุณ ฉันพยายามช่วย ChrisBo โดยแก้ไขการใช้ JavaScript ที่ไม่เหมาะสมของเขา ได้แก่ : var result = string.search (/ searchstring / i); กับสตริงการค้นหาที่เหมาะสมซึ่งเป็นวิธีการที่เขาใช้
Sergey Ilinsky

8
ถูกต้องของ Dan (แม้ว่าเขาอาจหมายถึงการพูดว่า " ไม่มีมาตรการ"): s = 'a[b'; r = new RegExp(s)ส่งผลให้เกิดข้อผิดพลาดทางไวยากรณ์ (คลาสของตัวละครที่ไม่ได้ถูก
ทำลาย

39

หากคุณเพียงแค่ค้นหาสตริงมากกว่าการแสดงออกปกติที่ซับซ้อนมากขึ้นคุณสามารถใช้indexOf()- แต่อย่าลืมพิมพ์เล็กทั้งสองสตริงก่อนเพราะ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);

หรือเป็นบรรทัดเดียว:

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

24

สมมติว่าเราต้องการที่จะหาตัวแปรสตริงในตัวแปรสตริงneedle haystackมีสาม gotchas:

  1. การใช้งานสากลควรหลีกเลี่ยงและstring.toUpperCase string.toLowerCaseใช้นิพจน์ทั่วไปที่ไม่สนใจตัวพิมพ์ใหญ่แทน ยกตัวอย่างเช่นตามมาด้วยvar needleRegExp = new RegExp(needle, "i");needleRegExp.test(haystack)
  2. needleโดยทั่วไปแล้วคุณอาจไม่ทราบว่าค่าของ ระวังว่าneedleไม่ได้มีการแสดงออกปกติใด ๆอักขระพิเศษ needle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");หนีเหล่านี้โดยใช้
  3. ในกรณีอื่น ๆ หากคุณต้องการจับคู่อย่างแม่นยำneedleและhaystackเพียงละเว้นกรณีและปัญหาอย่าลืมเพิ่ม"^"ตอนเริ่มต้นและ"$"ตอนท้ายของตัวสร้างนิพจน์ทั่วไปของคุณ

นำคะแนน (1) และ (2) มาประกอบการพิจารณาตัวอย่างจะเป็น:

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()ผลตอบแทนtrueถ้าsearchStringปรากฏที่หนึ่งตำแหน่งขึ้นไปหรือfalseอย่างอื่น


2

หากคุณกังวลเกี่ยวกับกรณี "คลาสอักขระที่ไม่ได้ทำลาย" การลบตัวอักษรที่ไม่ใช่ตัวอักษรและตัวเลขทั้งหมดจะเป็นประโยชน์:

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

2

ฉันชอบคำตอบของ @ CHR15TO ซึ่งแตกต่างจากคำตอบอื่น ๆ ที่ฉันเคยเห็นในคำถามที่คล้ายกันอื่น ๆ คำตอบนั้นจริง ๆ แล้วแสดงให้เห็นว่าผู้ใช้ระบุสตริงการค้นหาได้อย่างไร (แทนที่จะบอกว่าจำเป็น

อย่างไรก็ตามมันยังคงค่อนข้าง clunky และอาจค่อนข้างช้า เหตุใดจึงไม่มีวิธีแก้ปัญหาเฉพาะสำหรับความต้องการร่วมกันของโค้ด (และทำไมไม่รวมไว้ใน ES6 API BTW?)

คำตอบของฉัน [ https://stackoverflow.com/a/38290557/887092]สำหรับคำถามที่คล้ายกันเปิดใช้งานต่อไปนี้:

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

1

มีสองวิธีสำหรับการเปรียบเทียบแบบคำนึงถึงขนาดตัวพิมพ์:

  1. แปลงสตริงเป็นตัวพิมพ์ใหญ่แล้วเปรียบเทียบโดยใช้โอเปอเรเตอร์เข้มงวด ( ===) ผู้ปฏิบัติงานที่เข้มงวดปฏิบัติต่อตัวถูกดำเนินการอ่านอะไรได้ที่: http://www.thesstech.com/javascript/relational-logical-operators

  2. การจับคู่รูปแบบโดยใช้วิธีสตริง:

    ใช้วิธีสตริง "ค้นหา" สำหรับการค้นหาแบบไม่สนใจตัวพิมพ์ อ่านเกี่ยวกับวิธีการค้นหาและสตริงอื่น ๆ ได้ที่: 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>

1

ฉันทำสิ่งนี้บ่อยครั้งและใช้ต้นแบบ 5 บรรทัดง่าย ๆ ที่ยอมรับ varargs มันเป็นไปอย่างรวดเร็วและใช้งานได้ทุกที่

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

คุณสามารถทำให้ทุกอย่างเป็นตัวพิมพ์เล็ก:

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

-1

ฉันสังเกตเห็นว่าหากผู้ใช้ป้อนสตริงข้อความ แต่ปล่อยให้อินพุตโดยไม่เลือกตัวเลือกการเติมข้อความอัตโนมัติใด ๆ ไม่มีการตั้งค่าในอินพุตที่ซ่อนอยู่แม้ว่าสตริงจะตรงกับหนึ่งในอาร์เรย์ ดังนั้นด้วยความช่วยเหลือของคำตอบอื่น ๆ ฉันทำ:

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

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