te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>regex - How to check if contains all keywords in any order of string? RegExp Javascript - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

regex - How to check if contains all keywords in any order of string? RegExp Javascript - Stack Overflow

programmeradmin5浏览0评论

I want to check if a string have all input keywords in any order of the string. In much cases, the keywords are in any order, but exists in string.

Example(this is what I expect):

// Same order and have all keywords
"Hello world!".contains( "hello world" )       // true

// Same order and have all keywords
"Hello all in the world!".contains( "hello world" )       // true

// Any order but have all keywords
"Hello world!".contains( "world hello" )       // true

// Same order and all keywords
"Hello world!".contains( "worl hell" )         // true

// Have all keywords in any order
"Hello world!".contains( "world" )             // true

// No contains all keywords
"Hello world!".contains( "where you go" )      // false

// No contains all keywords
"Hello world!".contains( "z" )                 // false

// No contains all keywords
"Hello world!".contains( "z1 z2 z3" )          // false

// Contains all keywords in any order
"Hello world!".contains( "wo" )                // true

I try with:

/(?=\bhello\b)(?=\bworld\b)/i.test("hello world")      // false
/(?=.*?hello.*?)(?=.*?world.*?)/i.test("hello world")  // false
/^(?=\bhello\b)(?=\bworld\b).*?$/i.test("hello world") // false

I created some functions like:

// escape string to use in regexp
String.prototype.escape = function () {
    return this.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")
};
// check if empty string
String.prototype.isEmpty = function () {
    return this.length === 0;
};
// check if contain keywords...
String.prototype.contains = function (keywords) {
    var value  = '^(?=\\b' + keywords
        .escape()
        .replace(/(^\s+|\s+$)/ig, '')
        .replace(/\s+/, ' ')
        .split(/\s+/)
        .join('.*?)(?=.*?') + ').*$',
    reg = new RegExp(value, 'i'),
    text = this;
    return reg.test( this );
};

Thanks

I want to check if a string have all input keywords in any order of the string. In much cases, the keywords are in any order, but exists in string.

Example(this is what I expect):

// Same order and have all keywords
"Hello world!".contains( "hello world" )       // true

// Same order and have all keywords
"Hello all in the world!".contains( "hello world" )       // true

// Any order but have all keywords
"Hello world!".contains( "world hello" )       // true

// Same order and all keywords
"Hello world!".contains( "worl hell" )         // true

// Have all keywords in any order
"Hello world!".contains( "world" )             // true

// No contains all keywords
"Hello world!".contains( "where you go" )      // false

// No contains all keywords
"Hello world!".contains( "z" )                 // false

// No contains all keywords
"Hello world!".contains( "z1 z2 z3" )          // false

// Contains all keywords in any order
"Hello world!".contains( "wo" )                // true

I try with:

/(?=\bhello\b)(?=\bworld\b)/i.test("hello world")      // false
/(?=.*?hello.*?)(?=.*?world.*?)/i.test("hello world")  // false
/^(?=\bhello\b)(?=\bworld\b).*?$/i.test("hello world") // false

I created some functions like:

// escape string to use in regexp
String.prototype.escape = function () {
    return this.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")
};
// check if empty string
String.prototype.isEmpty = function () {
    return this.length === 0;
};
// check if contain keywords...
String.prototype.contains = function (keywords) {
    var value  = '^(?=\\b' + keywords
        .escape()
        .replace(/(^\s+|\s+$)/ig, '')
        .replace(/\s+/, ' ')
        .split(/\s+/)
        .join('.*?)(?=.*?') + ').*$',
    reg = new RegExp(value, 'i'),
    text = this;
    return reg.test( this );
};

Thanks

Share Improve this question edited Jan 19, 2017 at 17:56 Olaf Erlandsen asked Jan 19, 2017 at 17:27 Olaf ErlandsenOlaf Erlandsen 6,03611 gold badges47 silver badges78 bronze badges 7
  • Any or All of the keywords? – LukStorms Commented Jan 19, 2017 at 17:31
  • @LukStorms i want check if have all keywords in any order. Thanks – Olaf Erlandsen Commented Jan 19, 2017 at 17:32
  • @I.G.Pascual no, no is duplicated. See this example: "Hello all in the world!".contains( "hello world" ) I want this return true because have all keywords in any order – Olaf Erlandsen Commented Jan 19, 2017 at 17:58
  • @OlafErlandsen Its confusing. "Hello world!".contains( "world" ) . This example has just one keyword and the output is true. – pratZ Commented Jan 19, 2017 at 18:00
  • 1 Oh, BTW, Don't modify String.prototype!!! books.google.es/… , what you're doing is a plete madness, all the other js libraries you import depending on it could stop working!! – I.G. Pascual Commented Jan 19, 2017 at 21:30
 |  Show 2 more ments

6 Answers 6

Reset to default 7

The answer from I.G. Pascual shows how to construct a regex that solves the OP's problem. Below is working code demonstrating how to build such regexes dynamically, passing all the test cases from the OP.

function buildRegEx(str, keywords){
  return new RegExp("(?=.*?\\b" + 
    keywords
      .split(" ")
      .join(")(?=.*?\\b") +                     
    ").*", 
    "i"
  );
}

function test(str, keywords, expected){
  var result = buildRegEx(str, keywords).test(str) === expected
  console.log(result ? "Passed" : "Failed");
}

// Same order and have all keywords 
test("Hello world!", "hello world", true);
// Same order and have all keywords 
test("Hello all in the world!", "hello world", true);
// Any order but have all keywords 
test("Hello world!", "world hello", true);
// Same order and all keywords 
test("Hello world!", "worl hell", true);
// Have all keywords in any order 
test("Hello world!", "world", true);
// No contains all keywords 
test("Hello world!", "where you go", false);
// No contains all keywords
test("Hello world!", "z", false);
// No contains all keywords 
test("Hello world!", "z1 z2 z3", false);
// Contains all keywords in any order 
test("Hello world!", "wo", true);

You mean an unordered list of keywords: Regex - match multiple unordered words in a string, but removing the last \b part of each regex token

/(?=.*?\bhello)(?=.*?\bworld).*/i

With these type of regex all your test should pass now.

Check it in http://regexr./3f3ru

i makes it to ignore case sensitive, in case you need to check also Hello, wOrld, etc

String.prototype.contains = function(string){    
    var keywords = string.split(" ");
    var contain = true;

    for(var i = 0; i < keywords.length && contain; i++){
        if(keywords[i] == "") continue;

        var regex = new RegExp(keywords[i], "i");
        contain = contain && regex.test(this);
    }

    return contain;
}

An alternative to the lookahead-based option would be:

String.prototype.contains = function (keywordsStr) {
    var keywords = keywordsStr.split(/\s+/);
    return keywords.every(function(keyword)) {
        var reg = new RegExp(keyword.escape());
        return reg.test(this);
    }, this);
};

It's easy way to use .match() method to string. You can try this

Example:

var re = /(hello|world)/i;
var str = "Hello world!"; 
console.log('Do we found something?', Boolean(str.match(re)));

// for other
var re = /(hello|world)/i;       // true
var re = /(world|hello)/i;       // true
var re = /(worl|hell)/i;         // true
var re = /(this|is|my|world)/i;  // true
var re = /(where|you|go)/i;      // false
var re = /(z)/i;                 // false
var re = /(z1|z2|z3)/i;          // false
var re = /(wo)/i;                // true

result.filter(camp => search.map(keyword => camp.name.includes(keyword)).reduce((acc, curr) => acc && curr, true));

发布评论

评论列表(0)

  1. 暂无评论