繁体   English   中英

搜索数组中的多个元素

[英]Search for multiple elements in an array

我想在数组中检索与多个字符串匹配的所有元素( 所有这些元素和不必要的单词 ):就像一个搜索引擎,返回与term_searched#1 && term_searched#2匹配的所有结果。

这不是一个问题关于duplicates阵列中(有没有),但关于搜索元素的结合 :传统上,搜索是一个元素,由他本人或与他人脱节 (A | B | C)。 只想搜索(a && b && c)。

我试过了:

  • indexOf() :我只能使用一个元素来定位数组。
  • match()regex表达式中没有AND运算符(只有| -不幸的是,它是如此简单 )。 所以我试图注入这些regex表达式
    • /(?=element1).*(?=element2)/gim
    • /(?=element1)(?=element2)/gim请参阅此处

第一个regex表达式有效,但并非每次都有效:似乎非常脆弱...

所以我不知道我是朝着正确的方向( match )还是无法弄清楚正确的regex表达式是什么...需要您的建议。

// filter grid by searching on 'input' event
'input #search': (e)=> {
    var keypressed = e.currentTarget.value;

    // create array on 'space' input
    var keyarr = keypressed.toLowerCase().split(" ");

    // format each array's element into regex expression
    var keyarrReg = [];
    for(i = 0; i < keyarr.length; i++) {
        var reg = '(?=' + keyarr[i] + ')';
        keyarrReg.push(reg);
    }

    // array to regex string into '/(?=element1).*(?=element2)/gim' format
    var searching = new RegExp(keyarrReg.join(".*"), 'mgi');

    // set grid
    var grid = new Muuri('#gridre', {
        layout: {
            fillGaps: true,
        }
    });

    if (keypressed) {
        // filter all grid's items (grid of items is an array)
        grid.filter(function (item) {
            var searchoperator = item.getElement().textContent.toLowerCase().match(searching);
            // get items + only their text + lower case their text + return true (not false) in the value ('keypressed') is found in them
            //var searchoperator = item.getElement().textContent.toLowerCase().indexOf(keypressed.toLowerCase()) != -1;
            return searchoperator;
        }
        [....]

    }
}

使用适合我的初始代码的Gawil答案进行编辑(如有需要,可提供帮助)

// filter grid by searching on 'input' event
'input #search': (e)=> {
    var keypressed = e.currentTarget.value;

    // create array on 'space' input
    var keyarr = keypressed.toLowerCase().split(" ");

    // convert the array to a regex string, in a '^(?=.*word1)(?=.*word2).*$' format
    // here is Gawil's answer, formatted by Teemu 
    var searching = new RegExp('^(?=.*' + keyarr.join(')(?=.*') + ').*$', 'm');

    // set grid
    var grid = new Muuri('#gridre', {
        layout: {
            fillGaps: true,
        }
    });

    if (keypressed) {
        // filter all grid's items (grid of items is an array)
        grid.filter(function (item) {
            // get items + only their text + lower case their text + delete space between paragraphs
            var searchraw = item.getElement().textContent.toLowerCase().replace(/\r\n|\n|\r/gm,' ');
            var searchoperator = searchraw.match(searching);
            return searchoperator;
        }
        [....]

    }
}

下面的代码将记录包含单词catsdogs的数组的每个元素。
它使用正则表达式^(?=.*word1)(?=.*word2).*$
要处理新行,请改用此行:
^(?=(?:.|\\n)*word1)(?=(?:.|\\n)*word2).*$

您可以按照相同的逻辑添加任意数量的单词,并且不按单词的顺序进行计数。

它与您尝试过的非常相似,除了必须匹配字符串之前进行所有(?=)检查。 确实,您的第一个正则表达式仅在单词顺序正确时才有效(element1,然后是element2)。 您的第二个正则表达式几乎可以正常工作,但是您只写了前瞻性代码,因此它检查每个单词的存在,但不匹配任何单词。

 var words = ["cats", "dog"] var array = [ "this is a string", "a string with the word cats", "a string with the word dogs", "a string with both words cats and dogs", "cats rule everything", "dogs rule cats", "this line is for dog\\nbut cats prefer this one" ] var regexString = "^"; words.forEach(function(word) { regexString += ("(?=(?:.|\\n)*"+word+")"); }); var regex = new RegExp(regexString); array.forEach(function(str) { // Loop through the array if(str.match(regex)) { console.log(str); // Display if words have been found } }); 

如果我正确理解了您的问题,那么您将拥有一个字符串数组和一些关键字,这些关键字和关键字必须从数组中的每个索引中找到才能在搜索结果中接受。

您可以使用“白名单”,即regExp,其中关键字之间用|分隔| 然后遍历该数组,并在每个成员上创建一个与白名单匹配的数组。 只需将matchs数组的长度与关键字的数量进行比较,即可从matchs数组中删除重复项,然后检查所有关键字是否都在列表中。 像这样:

 function searchAll (arr, keywords) { var txt = keywords.split(' '), len = txt.length, regex = new RegExp(txt.join('|'), 'gi'), // A pipe separated whitelist hits; // The final results to return, an array containing the contents of the matched members // Create an array of the rows matching all the keywords hits = arr.filter(function (row) { var res = row.match(regex), // An array of matched keywords final, temp; if (!res) {return false;} // Remove the dups from the matches array temp = {}; // Temporary store for the found keywords final = res.filter(function (match) { if (!temp[match]) { // Add the found keyword to store, and accept the keyword to the final array return temp[match] = true; } return false; }); // Return matches count compared to keywords count to make sure all the keywords were found return final.length === len; }); return hits; } var txt = "Some text including a couple of numbers like 8 and 9. More text to retrieve, also containing some numbers 7, 8, 8, 8 and 9", arr = txt.split('.'), searchBut = document.getElementById('search'); searchBut.addEventListener('change', function (e) { var hits = searchAll(arr, e.target.value); console.log(hits); }); 
 <input id="search"> 

白名单的优点是,您不必知道文本中关键字的确切顺序,并且文本可以包含任何字符。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM