如何检查字符串是否包含来自JavaScript中子字符串数组的文本?


163

挺直的。在javascript中,我需要检查字符串是否包含数组中包含的任何子字符串。


map()新的HTML5-JavaScript版本中没有功能吗?我记得曾读过一些有关该主题的文章...
Martin Hennings

@马丁:好一点,没有map这么多somesome会有所帮助,但是您必须将其传递给函数。
TJ Crowder

Answers:


222

没有内置功能可以为您做到这一点,您必须为其编写一个函数。

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

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

...这会创建一个正则表达式,该表达式是您要查找的子字符串的一系列替换(例如one|two),并测试是否有匹配的子字符串,但是如果任何子字符串包含任何特殊字符在正则表达式(*[等)中,您必须先对其进行转义,而最好只进行无聊的循环。

现场示例:


在对该问题的评论中,Martin询问了Array.prototype.mapECMAScript5中的新方法。map没有太多帮助,但是some

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

现场示例:

尽管对polyfill来说是微不足道的,但您仅在兼容ECMAScript5的实现中使用它。


2020年更新some使用箭头功能(ES2015 +)可以使示例更简单,您可以使用includes而不是indexOf

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

现场示例:

甚至扔掉bind它,尽管对我来说箭头功能更具可读性:

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

现场示例:


2
“请介意,这确实意味着一些开销……” 但无所谓
TJ Crowder 2013年

您可以通过删除除'|'之外的所有正则表达式字符来扩展上述解决方案new RegExp(substrings.join("|").replace(/[^\w\s^|]/gi, '')).test(string)
user007

使用indexOf可能会太模糊并且产生奇怪的结果。可以简单地使用equals运算符将其与字符串匹配。例如,('disconnect'.indexOf('connect') >= 0) === true但是('disconnect' === 'conenct') === false
kylewelsby

@halfcube:嗯?恐怕我不了解你。在上面的回答没有迹象表明'disconnect' === 'connect'会是什么,但false。而且,indexOf它不是模糊的,确实非常明确地定义了。
TJ Crowder

indexOf将同时匹配disconnectconnect在我所经历的情况下,这是两个不同的情况下,我想在有条件的返回结果。
kylewelsby

54
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
   }
}

50

一线解决方案

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

返回true\false子字符串exists\does'nt exist

需要ES6支持


使用箭头功能的绝佳解决方案
GuerillaRadio

7
你是孩子...早在我还是个孩子的时候,我们就不得不使用称为“ for”循环的这些东西,并且你不得不使用多行,并且知道你的数组是基于1还是零,是的...一半的时间这是错误的,因此必须进行调试并寻找一个名为“ i”的小虫子。
aamarks '18

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

1
最容易理解的一个!
达里尔·H

另外,它返回字符串中单词的首次出现,这非常有帮助。不仅是对/错。
Kai Noack

20

对于谷歌搜索的人,

肯定的答案应该是。

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

2
或更短的时间:if(substrings.some(v => v === str)){
kofifus

10
请注意,这是对一个稍有不同的问题的解答,该问题询问一个字符串是否包含子字符串数组中的文本。此代码检查字符串是否为子字符串之一。我想这取决于“包含”的含义。
fcrick

8
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 < arr.length
GreySage

3

如果数组不大,则可以使用循环并针对每个子字符串分别检查字符串indexOf()。另外,您也可以用子字符串构造一个正则表达式,以提高效率,也可以不提高效率。


假设我们有一个100个子字符串的列表。哪种方法更有效:RegExp或循环?
Diyorbek Sadullayev

3

Javascript函数使用搜索字符串或搜索字符串数组来搜索标签或关键字的数组。(使用ES5的 一些数组方法和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
}

2

我并不是建议您去扩展/修改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


2

利用TJ Crowder的解决方案,我创建了一个原型来处理此问题:

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

2
substringsArray.every(substring=>yourBigString.indexOf(substring) === -1)

获得全力支持;)


2

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

    var specsFilter = [.....];
    var yourString = "......";

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

1

使用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

1

这太迟了,但是我遇到了这个问题。在我自己的项目中,我使用以下命令检查字符串是否在数组中:

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

这样,您可以采用预定义的数组并检查它是否包含字符串:

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

1

以TJ 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 ...'));


1

如果您要使用由完整的“单词”组成的一长串子字符串,这些单词之间用空格或任何其他公共字符分隔,则搜索可能会更聪明。

首先将您的字符串分成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,而这样做所花费的时间/内存超过了收益。


1

要获得全面支持(@ricca的版本除外)。

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


0

您可以像这样检查:

<!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>

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.