jQuery/JavaScript检查字符串是否包含多个子字符串

12
我需要检查一个字符串是否含有三个子串中的任意一个,如果是,就要实现一个函数。我知道可以使用 if (str.indexOf("term1") >= 0) 来检查一个子串,但是有没有一种方法可以检查多个子串,而不用多次使用这段代码呢?
谢谢!

1
如果(str.indexOf(“term1”)>= 0 || str.indexOf(“term2”)> = 0 || str.indexOf(“term3”)> = 0) - Alvin Wong
7个回答

32
if (/term1|term2|term3/.test("your string")) {
   //youre code
}

你不必解释为什么要 downvote,但我猜并不是每个人都喜欢正则表达式。在这种情况下,它们并不是必需的,有些人可能会说它们使代码难以阅读。 - Ash Burlaczenko
7
它们既简单又优雅。如果我懂正则表达式,为什么还要使用复杂的OR(||)语句或循环呢? - elrado
2
回答的解释为什么会缺失?你为什么要要求解释负评?不要索取你没有给予的东西。 - guradio
1
很棒的答案!对我有用,而且帮助我找到了一个稍微容易跟进的版本:str =“你的字符串”;str.match(/(term1|term2|term3)/g);但在这种情况下,match在技术上是次优的。 - Jason R. Escamilla
https://stackoverflow.com/questions/45346171/js-regex-to-find-multiple-substrings-in-string 是另一种形式。 - Jason R. Escamilla

28

这可以动态而优雅地实现您所尝试做的事情。

const terms = ["term1", "term2", "term3"]
const str = "very large string to check for term1, tern2, etc ..."

// check if the string has some of the terms
const result1 = terms.some(term => str.includes(term))

// check if the string has all the terms
const result2 = terms.every(term => str.includes(term))

这也使得过滤字符串数组中的子字符串数组变得容易。

const terms = ["term1", "term2", "term3"]
const strings = ["very large string text ....", "another large string text"] 

// filter the strings of the array that contain some of the substrings we're looking for
const result1 = strings.filter(str => terms.some(term => str.includes(term)))

// filter the strings of the array that contain all the substrings we're looking for
const result2 = strings.filter(str => terms.every(term => str.includes(term)))

这是一个很棒的解决方案。谢谢您。 - Adam

10
你可以使用循环,甚至可以创建一个辅助函数,如下所示:

您可以使用循环。甚至可以创建一个辅助函数,如下所示:

function ContainsAny(str, items){
    for(var i in items){
        var item = items[i];
        if (str.indexOf(item) > -1){
            return true;
        }

    }
    return false;
}

然后您可以这样调用:
if(ContainsAny(str, ["term1", "term2", "term3"])){
   //do something
}

从问题中:“我需要检查一个字符串是否有三个子字符串之一”,并不要求它们全部都存在,只需要至少有一个即可。 - Anthony Grist

4
.map()函数可用于将术语数组转换为一个布尔数组,指示是否找到每个术语。然后检查任何一个布尔值是否为true
给定一个terms数组:
const terms = ['term1', 'term2', 'term3'];

这行代码将会在string中包含任何terms时返回true:
terms.map((term) => string.includes(term)).includes(true);       

三个例子:

terms.map((term) => 'Got term2 here'.includes(term)).includes(true);       //true
terms.map((term) => 'Not here'.includes(term)).includes(true);             //false
terms.map((term) => 'Got term1 and term3'.includes(term)).includes(true);  //true

或者,如果你想将代码封装成可重复使用的hasTerm()函数:

const hasTerm = (string, terms) =>
   terms.map(term => string.includes(term)).includes(true);

hasTerm('Got term2 here', terms);       //true
hasTerm('Not here', terms);             //false
hasTerm('Got term1 and term3', terms);  //true

尝试一下:
https://codepen.io/anon/pen/MzKZZQ?editors=0012 .map()文档:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map 注:Note:该答案优化了简洁性和可读性。如果需要处理大量的术语数组,请使用在找到术语后停止循环的循环。

这是o(n)的时间复杂度,有点慢。 - Rongeegee
抱歉,@Rongeegee,但你的一概而论是错误的,因为你没有针对开发者进行优化。粗体注释清楚地解释了优化标准,甚至提到了根据需要进行优化的备选策略。 - Dem Pilafian

3
也许是这样的:

if (str.indexOf("term1") >= 0 || str.indexOf("term2") >= 0 || str.indexOf("term3") >= 0) 
{
 //your code
}

2
不过对于数量未知的术语来说并不理想。 - musefan
1
我同意,但他要求3个子字符串。 - freshbm

2
你可以做类似以下的操作:
function isSubStringPresent(str){
    for(var i = 1; i < arguments.length; i++){
        if(str.indexOf(arguments[i]) > -1){
            return true;
        }
    }

    return false;
}

isSubStringPresent('mystring', 'term1', 'term2', ...)

以前从没见过这种用法,使用了额外的参数。你能给我指一下文档吗? - Ash Burlaczenko
有趣的是,我以前从未听说过 arguments...虽然我认为这可能会容易被重新定义? - musefan
每个 JavaScript 方法都会获得一个名为 arguments 的隐藏参数,它是一个类似数组的结构,包含传递给该方法的所有参数。这就像 Java 中的可变参数。 - Arun P Johny
2
另一方面,你的代码片段不对吗?如果任何一个子字符串不在字符串中,你将退出并返回false。难道OP不想检查至少有一个子字符串在字符串中吗? - Ash Burlaczenko
@AshBurlaczenko错过了,我以为是所有三个,已经做出更改。 - Arun P Johny

0

如果你想检查多个字符串匹配并将它们标记出来,这段代码片段可以实现。

function highlightMatch(text, matchString) {
    let textArr = text.split(' ');
    let returnArr = [];
    
    for(let i=0; i<textArr.length; i++) {
        let subStrMatch = textArr[i].toLowerCase().indexOf(matchString.toLowerCase());
        
        if(subStrMatch !== -1) {
            let subStr = textArr[i].split('');
            let subStrReturn = [];
            
            for(let j=0 ;j<subStr.length; j++) {
                
                if(j === subStrMatch) {
                    subStrReturn.push('<strong>' + subStr[j]);    
                } else if (j === subStrMatch + (matchString.length-1)){
                    subStrReturn.push(subStr[j] + '<strong>');
                } else {
                    subStrReturn.push(subStr[j]);
                }
            }
            returnArr.push(subStrReturn.join(''));
        } else {
            returnArr.push(textArr[i]);
        }
    }
    return returnArr;
}


highlightMatch('Multi Test returns multiple results', 'multi'); 
=>  (5) ['<strong>Multi<strong>', 'Test', 'returns', '<strong>multi<strong>ple', 'results']

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接