【问题标题】:Contains case insensitive包含不区分大小写
【发布时间】:2012-02-18 02:37:30
【问题描述】:

我有以下几点:

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

我喜欢做的是让Ral不区分大小写,这样它就可以是RAlrAl等并且仍然匹配。

有没有办法说Ral 必须不区分大小写?

【问题讨论】:

  • 我认为不区分大小写的正则表达式是更优雅的解决方案,但每个人都应该记住直接从用户输入创建RegExp 的陷阱。例如,用户可以输入*,然后RegExp 构造函数中会抛出错误。接受的解决方案没有这个问题。

标签: javascript string case-sensitive case-insensitive


【解决方案1】:

referrer 之后添加.toUpperCase()。此方法将字符串转换为大写字符串。然后,使用.indexOf() 使用RAL 而不是Ral

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

同样可以使用正则表达式来实现(当您想要针对动态模式进行测试时特别有用):

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

【讨论】:

  • 后一种方法更正确;对于土耳其语 I 和任何其他此类有问题的大写/小写对,前者将失败:i18nguy.com/unicode/turkish-i18n.html
  • 土耳其语最好使用toLocaleLowerCase() (ref)
  • @Maslow 这个问题的例子是关于测试用例不敏感。如果要获取索引,使用String's .search方法:var index = referrer.search(/Ral/i);
  • 动态正则表达式方法增加的复杂性是,如果搜索字符串,例如“Ral”,包含正则表达式特殊字符,例如 $.*?等等,你会遇到问题,所以你需要转义特殊字符,请参阅 Mike Samuel 在这篇文章中的回答:endsWith in JavaScript
  • 正如其他人指出的那样,最好使用 toUpperCase()。见msdn.microsoft.com/en-us/library/bb386042.aspx
【解决方案2】:

另一种选择是使用以下搜索方法:

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

它看起来更优雅,然后将整个字符串转换为小写,它可能更有效。
使用toLowerCase(),代码对字符串进行两次传递,一次传递整个字符串以将其转换为小写,另一次传递是查找所需的索引。
使用 RegExp 时,代码会遍历字符串,它看起来与所需的索引匹配。

因此,在长字符串上我建议使用RegExp 版本(我猜想在短字符串上这种效率来自于创建RegExp 对象)

【讨论】:

  • 根据我的测试,这也快了很多:jsperf.com/case-insensitive-indexof
  • 截至 2018 年 10 月 24 日,toLowerCase 在 Chrome 中大获全胜。 toLowerCase (95,914,378 - ±0.89% - 最快), 正则表达式 indexOf (269,307 - ±0.87% 100% 慢)
  • 看来 JSPerf 现在已经死了,所以我在 JSBenchme 上重新创建了测试:jsbench.me/bckqv6ii1c/1 截至 2021 年,M1 Macbook Air 正则表达式比 indexOf 慢 99.43%。
  • 对于性能极客来说,使用RegExp.test 在我的机器上使用相同的基准测试更快。所以在这个例子中:(new RegExp('Ral', 'i')).test(referrer)
【解决方案3】:

从 ES2016 开始,您还可以使用稍微更好/更简单/更优雅的方法(区分大小写):

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

或(不区分大小写):

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

以下是.indexOf().includes() 的一些比较: https://dev.to/adroitcoder/includes-vs-indexof-in-javascript

【讨论】:

  • 我不认为包含不区分大小写
  • @Kyles includes 在 Chrome 中区分大小写:试试 'fooBar'.includes('bar') ==> false
【解决方案4】:

使用正则表达式:

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

或者,使用.toLowerCase()

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

【讨论】:

【解决方案5】:

这里有几种方法。

如果您只想对此实例执行不区分大小写的检查,请执行以下操作。

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

或者,如果您定期执行此检查,您可以向String 添加一个类似indexOf() 的新方法,但不区分大小写。

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

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

【讨论】:

  • 对于支持defineProperty的现代浏览器,我建议Object.defineProperty(String.prototype, 'indexOfInsensitive', {value: function(s,b){return this.toLowerCase().indexOf((s+'').toLowerCase(),b);}});。两个更新:使用(s+'') 进行显式字符串转换,并且在循环中不可枚举(for(var i in '') ... 不显示indexOfInsensitive
【解决方案6】:

你可以试试这个

str = "Wow its so COOL"
searchStr = "CoOl"

console.log(str.toLowerCase().includes(searchStr.toLowerCase()))

【讨论】:

    【解决方案7】:
    if (referrer.toUpperCase().indexOf("RAL") == -1) { ...
    

    【讨论】:

    • @Domenic:在充分尊重土耳其文化的情况下,土耳其应该考虑进行拼写改革以简化这一方面。中国有很多simplification reforms,而土耳其的人口不到中国的10%,字母表也简单得多。可以做到的。
    【解决方案8】:

    任何语言的示例:

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

    【讨论】:

    • 哇。我发现它非常有用。谢谢你。
    【解决方案9】:

    这里是按照 ES6 的性能降序排列的选项

    包括

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

    IndexOf(这有时会产生与 Includes 相似或更好的结果)

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

    匹配

    if (referrer.match(new RegExp("Ral", 'i'))) { ... }
    

    基准测试结果:https://jsben.ch/IBbnl

    【讨论】:

      【解决方案10】:

      现在是 2016 年,没有明确的方法可以做到这一点吗?我希望有一些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
      • 不要添加后缀词 - IndexOf 指的是以下参数。所以改为前缀一些东西。
      • 不要使用“不区分大小写”前缀会很长
      • “自然”是一个很好的候选,因为默认的区分大小写的比较对人类来说首先是不自然的。

      为什么不...:

      • toLowerCase() - 可能在同一字符串上重复调用 toLowerCase。
      • RegExp - 用变量搜索很尴尬。即使是 RegExp 对象也很尴尬,不得不转义字符

      【讨论】:

      • @RolandIllig 哎哟。我的回答不适应其他文化,这是一个缺点。我欢迎任何关于扩大对更多文化的支持的见解,有了合作者,世界会变得更美好。
      【解决方案11】:

      使用以下代码进行更好的搜索,

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

      在第一个 alert() 中,JavaScript 返回“-1” - 换句话说,indexOf() 没有找到匹配项:这仅仅是因为“JavaScript”在第一个字符串中是小写的,并且在第二。要使用 indexOf() 执行不区分大小写的搜索,您可以将两个字符串都设为大写或小写。这意味着,与第二个 alert() 一样,JavaScript 只会检查您要查找的字符串是否出现,忽略大小写。

      参考, http://freewebdesigntutorials.com/javaScriptTutorials/jsStringObject/indexOfMethod.htm

      【讨论】:

        【解决方案12】:

        如果referrer是一个数组,可以使用findIndex()

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

        【讨论】:

          【解决方案13】:

          这样更好~!

          if (~referrer.toUpperCase().indexOf("RAL")) { 
              console.log("includes")
          }
          

          【讨论】:

          • 如何“更好”?
          【解决方案14】:

          这是我的看法:

          脚本

          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

          【讨论】:

            猜你喜欢
            • 2023-04-02
            • 2011-10-20
            • 2012-02-03
            • 2015-01-22
            • 2013-01-16
            • 2014-08-04
            • 1970-01-01
            • 2017-09-02
            相关资源
            最近更新 更多