【问题标题】:How to check if a string contains text from an array of substrings in JavaScript?如何检查字符串是否包含 JavaScript 中子字符串数组中的文本?
【发布时间】:2011-07-31 18:05:35
【问题描述】:

非常直接。在 javascript 中,我需要检查一个字符串是否包含数组中保存的任何子字符串。

【问题讨论】:

  • 在新的 HTML5-JavaScript 版本中不是有 map() 函数吗?我记得我读过一些关于那个主题的东西......
  • @Martin:好点,不是map,而是somesome 会有所帮助,但您必须向它传递一个函数。

标签: javascript arrays string substring contains


【解决方案1】:

没有任何内置功能可以为您做到这一点,您必须为它编写一个函数,尽管它可以只是对 some 数组方法的回调。

两种方法适合您:

  • 数组some方法
  • 正则表达式

数组some

数组some 方法(在 ES5 中添加)使这变得非常简单:

if (substrings.some(function(v) { return str.indexOf(v) >= 0; })) {
    // There's at least one
}

使用箭头函数和新的includes 方法(都是 ES2015+)更好:

if (substrings.some(v => str.includes(v))) {
    // There's at least one
}

现场示例:

const substrings = ["one", "two", "three"];
let str;

// Setup
console.log(`Substrings: ${substrings}`);

// Try it where we expect a match
str = "this has one";
if (substrings.some(v => str.includes(v))) {
    console.log(`Match using "${str}"`);
} else {
    console.log(`No match using "${str}"`);
}

// Try it where we DON'T expect a match
str = "this doesn't have any";
if (substrings.some(v => str.includes(v))) {
    console.log(`Match using "${str}"`);
} else {
    console.log(`No match using "${str}"`);
}

正则表达式

如果您知道字符串不包含任何正则表达式中的特殊字符,那么您可以作弊,如下所示:

if (new RegExp(substrings.join("|")).test(string)) {
    // At least one match
}

...它为您正在寻找的子字符串(例如,one|two)创建一个由一系列交替组成的正则表达式,并测试它们中的任何一个是否匹配,但如果任何子字符串包含正则表达式中的特殊字符(*[ 等),则必须先将它们转义,并且最好只执行无聊的循环。有关逃避它们的信息,请参阅this question's answers

现场示例:

const substrings = ["one", "two", "three"];
let str;

// Setup
console.log(`Substrings: ${substrings}`);

// Try it where we expect a match
str = "this has one";
if (new RegExp(substrings.join("|")).test(str)) {
    console.log(`Match using "${str}"`);
} else {
    console.log(`No match using "${str}"`);
}

// Try it where we DON'T expect a match
str = "this doesn't have any";
if (new RegExp(substrings.join("|")).test(str)) {
    console.log(`Match using "${str}"`);
} else {
    console.log(`No match using "${str}"`);
}

【讨论】:

    【解决方案2】:

    一条线解决方案

    substringsArray.some(substring=>yourBigString.includes(substring))
    

    如果子字符串为exists\does'nt exist,则返回true\false

    需要 ES6 支持

    【讨论】:

    • 使用箭头函数的绝佳解决方案
    • 你们这些孩子......当我还是个孩子的时候,我们不得不使用这些称为“for”循环的东西,并且您必须使用多行并知道您的数组是基于 1 还是基于 0,是的...一半的时间你弄错了,不得不调试并寻找一个叫做“i”的小虫子。
    【解决方案3】:
    var yourstring = 'tasty food'; // the string to check against
    
    
    var substrings = ['foo','bar'],
        length = substrings.length;
    while(length--) {
       if (yourstring.indexOf(substrings[length])!=-1) {
           // one of the substrings is in yourstring
       }
    }
    

    【讨论】:

      【解决方案4】:
      function containsAny(str, substrings) {
          for (var i = 0; i != substrings.length; i++) {
             var substring = substrings[i];
             if (str.indexOf(substring) != - 1) {
               return substring;
             }
          }
          return null; 
      }
      
      var result = containsAny("defg", ["ab", "cd", "ef"]);
      console.log("String was found in substring " + result);
      

      【讨论】:

      • 最容易理解的!
      • 加上它返回字符串中第一次出现的单词,这非常有帮助。不仅是真/假。
      • 什么是 es6 等价物?
      【解决方案5】:

      对于谷歌搜索的人来说,

      可靠的答案应该是。

      const substrings = ['connect', 'ready'];
      const str = 'disconnect';
      if (substrings.some(v => str === v)) {
         // Will only return when the `str` is included in the `substrings`
      }
      

      【讨论】:

      • 或更短:if (substrings.some(v => v===str)) {
      • 请注意,这是对一个略有不同的问题的回答,该问题询问字符串是否包含子字符串数组中的文本。此代码检查字符串是否 子字符串之一。取决于我想的“包含”是什么意思。
      【解决方案6】:

      这是 (IMO)迄今为止最好的解决方案。这是一个现代 (ES6) 解决方案:

      • 高效(一行!)
      • 避免循环
      • 与其他答案中使用的 some() 函数不同,这个函数不仅返回布尔值 (true/false)
      • 相反,它要么返回子字符串(如果在数组中找到它),要么返回未定义
      • 更进一步,允许您选择是否需要部分子字符串匹配(以下示例)

      享受吧!



      const arrayOfStrings = ['abc', 'def', 'xyz'];
      const str = 'abc';
      const found = arrayOfStrings.find(v => (str === v));
      

      在这种情况下,found 将设置为“abc”。这适用于 exact 字符串匹配。

      如果你改用:

      const found = arrayOfStrings.find(v => str.includes(v));
      

      在这种情况下,found 将再次设置为“abc”。这不允许部分匹配,所以如果 str 设置为 'ab',found 将是未定义的。


      而且,如果您希望部分匹配起作用,只需将其翻转即可:
      const found = arrayOfStrings.find(v => v.includes(str));
      

      相反。因此,如果 str 设置为 'ab',found 将设置为 'abc'。

      简单易懂!



      【讨论】:

        【解决方案7】:
        var str = "texttexttext";
        var arr = ["asd", "ghj", "xtte"];
        for (var i = 0, len = arr.length; i < len; ++i) {
            if (str.indexOf(arr[i]) != -1) {
                // str contains arr[i]
            }
        }
        

        编辑: 如果测试的顺序无关紧要,您可以使用它(只有一个循环变量):

        var str = "texttexttext";
        var arr = ["asd", "ghj", "xtte"];
        for (var i = arr.length - 1; i >= 0; --i) {
            if (str.indexOf(arr[i]) != -1) {
                // str contains arr[i]
            }
        }
        

        【讨论】:

        • 您的第一个示例不需要len 变量,只需检查i &lt; arr.length
        【解决方案8】:

        这已经很晚了,但我刚刚遇到了这个问题。在我自己的项目中,我使用以下方法检查字符串是否在数组中:

        ["a","b"].includes('a')     // true
        ["a","b"].includes('b')     // true
        ["a","b"].includes('c')     // false
        

        这样你可以获取一个预定义的数组并检查它是否包含一个字符串:

        var parameters = ['a','b']
        parameters.includes('a')    // true
        

        【讨论】:

        • 这是这里最干净的答案。非常感谢!
        【解决方案9】:
        substringsArray.every(substring=>yourBigString.indexOf(substring) === -1)
        

        为了全力支持 ;)

        【讨论】:

          【解决方案10】:

          最佳答案在这里: 这也是不区分大小写的

              var specsFilter = [.....];
              var yourString = "......";
          
              //if found a match
              if (specsFilter.some((element) => { return new RegExp(element, "ig").test(yourString) })) {
                  // do something
              }
          

          【讨论】:

            【解决方案11】:

            寻求全面支持(除了@ricca 的verions)。

            wordsArray = ['hello', 'to', 'nice', 'day']
            yourString = 'Hello. Today is a nice day'.toLowerCase()
            result = wordsArray.every(w => yourString.includes(w))
            console.log('result:', result)

            【讨论】:

              【解决方案12】:

              如果数组不大,您可以循环并使用indexOf() 分别针对每个子字符串检查字符串。或者,您可以使用子字符串作为替代构造一个正则表达式,这可能会或可能不会更有效。

              【讨论】:

              • 假设我们有一个包含 100 个子字符串的列表。哪种方式更有效:正则表达式还是循环?
              【解决方案13】:

              使用搜索字符串或搜索字符串数组搜索标签或关键字数组的 JavaScript 函数。 (使用 ES5 some 数组方法和 ES6 箭头函数

              // returns true for 1 or more matches, where 'a' is an array and 'b' is a search string or an array of multiple search strings
              function contains(a, b) {
                  // array matches
                  if (Array.isArray(b)) {
                      return b.some(x => a.indexOf(x) > -1);
                  }
                  // string match
                  return a.indexOf(b) > -1;
              }
              

              示例用法:

              var a = ["a","b","c","d","e"];
              var b = ["a","b"];
              if ( contains(a, b) ) {
                  // 1 or more matches found
              }
              

              【讨论】:

                【解决方案14】:

                并不是我建议你去扩展/修改String 的原型,但这就是我所做的:

                String.prototype.includes()

                String.prototype.includes = function (includes) {
                    console.warn("String.prototype.includes() has been modified.");
                    return function (searchString, position) {
                        if (searchString instanceof Array) {
                            for (var i = 0; i < searchString.length; i++) {
                                if (includes.call(this, searchString[i], position)) {
                                    return true;
                                }
                            }
                            return false;
                        } else {
                            return includes.call(this, searchString, position);
                        }
                    }
                }(String.prototype.includes);
                
                console.log('"Hello, World!".includes("foo");',          "Hello, World!".includes("foo")           ); // false
                console.log('"Hello, World!".includes(",");',            "Hello, World!".includes(",")             ); // true
                console.log('"Hello, World!".includes(["foo", ","])',    "Hello, World!".includes(["foo", ","])    ); // true
                console.log('"Hello, World!".includes(["foo", ","], 6)', "Hello, World!".includes(["foo", ","], 6) ); // false

                【讨论】:

                  【解决方案15】:

                  基于 T.J Crowder 的回答

                  使用转义的 RegExp 来测试至少出现一个子字符串的“至少一次”。

                  function buildSearch(substrings) {
                    return new RegExp(
                      substrings
                      .map(function (s) {return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');})
                      .join('{1,}|') + '{1,}'
                    );
                  }
                  
                  
                  var pattern = buildSearch(['hello','world']);
                  
                  console.log(pattern.test('hello there'));
                  console.log(pattern.test('what a wonderful world'));
                  console.log(pattern.test('my name is ...'));

                  【讨论】:

                    【解决方案16】:

                    来自 T.J. Crowder 的解决方案,我创建了一个原型来处理这个问题:

                    Array.prototype.check = function (s) {
                      return this.some((v) => {
                        return s.indexOf(v) >= 0;
                      });
                    };
                    

                    【讨论】:

                      【解决方案17】:

                      使用 underscore.js 或 lodash.js,您可以对字符串数组执行以下操作:

                      var contacts = ['Billy Bob', 'John', 'Bill', 'Sarah'];
                      
                      var filters = ['Bill', 'Sarah'];
                      
                      contacts = _.filter(contacts, function(contact) {
                          return _.every(filters, function(filter) { return (contact.indexOf(filter) === -1); });
                      });
                      
                      // ['John']
                      

                      在单个字符串上:

                      var contact = 'Billy';
                      var filters = ['Bill', 'Sarah'];
                      
                      _.every(filters, function(filter) { return (contact.indexOf(filter) >= 0); });
                      
                      // true
                      

                      【讨论】:

                        【解决方案18】:

                        如果您正在处理由空格或任何其他常见字符分隔的完整“单词”组成的一长串子字符串,那么您的搜索可能会有点聪明。

                        首先将字符串分成 X 组,然后是 X+1,然后是 X+2,...,直到 Y。X 和 Y 应该分别是子字符串中单词最少和最多的单词数。例如,如果 X 为 1,Y 为 4,则“Alpha Beta Gamma Delta”变为:

                        “Alpha”“Beta”“Gamma”“Delta”

                        “Alpha Beta”“Beta Gamma”“Gamma Delta”

                        “Alpha Beta Gamma”“Beta Gamma Delta”

                        “Alpha Beta Gamma Delta”

                        如果 X 为 2 而 Y 为 3,那么您将省略第一行和最后一行。

                        现在,如果将其插入到 Set(或 Map)中,您可以快速搜索此列表,比通过字符串比较快得多。

                        缺点是您无法搜索“ta Gamm”之类的子字符串。当然,您可以通过按字符而不是按单词拆分来实现这一点,但是您通常需要构建一个庞大的 Set,并且这样做所花费的时间/内存超过了好处。

                        【讨论】:

                          【解决方案19】:
                          convert_to_array = function (sentence) {
                               return sentence.trim().split(" ");
                          };
                          
                          let ages = convert_to_array ("I'm a programmer in javascript writing script");
                          
                          function confirmEnding(string) {
                          let target = "ipt";
                              return  (string.substr(-target.length) === target) ? true : false;
                          }
                          
                          function mySearchResult() {
                          return ages.filter(confirmEnding);
                          }
                          
                          mySearchResult();
                          

                          您可以像这样检查并使用过滤器返回匹配单词的数组

                          【讨论】:

                            【解决方案20】:

                            你可以这样检查:

                            <!DOCTYPE html>
                            <html>
                               <head>
                                  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
                                  <script>
                                     $(document).ready(function(){
                                     var list = ["bad", "words", "include"] 
                                     var sentence = $("#comments_text").val()
                            
                                     $.each(list, function( index, value ) {
                                       if (sentence.indexOf(value) > -1) {
                                            console.log(value)
                                        }
                                     });
                                     });
                                  </script>
                               </head>
                               <body>
                                  <input id="comments_text" value="This is a bad, with include test"> 
                               </body>
                            </html>
                            

                            【讨论】:

                              【解决方案21】:

                              我遇到了这样的问题。我有一个 URL,我想检查链接是否以图像格式或其他文件格式结尾,具有图像格式数组。这是我所做的:

                              const imagesFormat = ['.jpg','.png','.svg']
                              const link = "https://res.cloudinary.com/***/content/file_padnar.pdf"
                              const isIncludes = imagesFormat.some(format => link.includes(format))
                                  
                              // false
                              

                              【讨论】:

                                【解决方案22】:
                                let obj = [{name : 'amit'},{name : 'arti'},{name : 'sumit'}];
                                let input = 'it';
                                

                                使用过滤器:

                                obj.filter((n)=> n.name.trim().toLowerCase().includes(input.trim().toLowerCase()))
                                

                                【讨论】:

                                【解决方案23】:

                                var str = "A for apple"
                                var subString = ["apple"]
                                
                                console.log(str.includes(subString))

                                【讨论】:

                                  猜你喜欢
                                  • 1970-01-01
                                  • 2010-12-19
                                  相关资源
                                  最近更新 更多