Javascript 正则表达式以任何顺序匹配查询中的所有单词

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13911053/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 15:06:20  来源:igfitidea点击:

Regular Expression to MATCH ALL words in a query, in any order

javascriptjqueryregex

提问by kayen

I'm trying to build a search feature for a project which narrows down items based on a user search input and if it matches the keywords listed against items. For this, I'm saving the item keywords in a dataattribute and matching the query with these keywords using a RegExp pattern.

我正在尝试为一个项目构建一个搜索功能,该功能根据用户搜索输入缩小项目范围,并且它是否与针对项目列出的关键字相匹配。为此,我将项目关键字保存在data属性中,并使用 RegExp 模式将查询与这些关键字进行匹配。

I'm currently using this expression, which I know is not correct and need your help on that:

我目前正在使用这个表达式,我知道这是不正确的,需要你的帮助:

new RegExp('\\b(' + query + ')', 'gi')))where query is |separated values of the query entered by the user (e.g. \\b(meat|pasta|dinner)). This returns me a match even if there is only 1 match, say for example - meat

new RegExp('\\b(' + query + ')', 'gi')))其中 query 是|用户输入的查询的分隔值(例如\\b(meat|pasta|dinner))。即使只有 1 个匹配项,这也会返回匹配项,例如 -meat

Just to throw some context, here's a small example:

只是为了抛出一些上下文,这是一个小例子:

If a user types: meat pasta dinnerit should list all items which have ALL the 3 keywords listed against them i.e. meatpastaand dinner. These are independent of the order they're typed in.

如果用户键入:meat pasta dinner它应该列出所有针对它们列出的所有 3 个关键字的项目,即meatpastadinner。这些与它们的输入顺序无关。

Can you help me with an expression which will match ALL words in a query, in any order?

你能帮我一个表达式,以任何顺序匹配查询中的所有单词吗?

回答by stema

You can achieve this will lookahead assertions

你可以实现这会先行断言

^(?=.*\bmeat\b)(?=.*\bpasta\b)(?=.*\bdinner\b).+

See it here on Regexr

在 Regexr 上看到它

(?=.*\bmeat\b)is a positive lookahead assertion, that ensures that \bmeat\bis somewhere in the string. Same for the other keywords and the .+is then actually matching the whole string, but only if the assertions are true.

(?=.*\bmeat\b)是一个积极的前瞻断言,确保它\bmeat\b在字符串中的某个地方。其他关键字相同,.+然后实际上匹配整个字符串,但前提是断言为真。

But it will match also on "dinner meat Foobar pasta"

但它也会与“晚餐肉 Foobar 意大利面”相匹配

回答by ColBeseder

your regex looks pretty good:

你的正则表达式看起来不错:

\b(meat|pasta|dinner)\b

Check that the length of matches equals the number of keywords (in this case, three):

检查匹配的长度是否等于关键字的数量(在本例中为三个):

string.match(re).length === numberOfKeywords

where reis the regex with a gflag, stringis the data and numberOfKeywordsis the number of keywords

哪里re是带g标志的正则表达式,string是数据,numberOfKeywords是关键字的数量

This assumes that there are no repeated keywords.

这假设没有重复的关键字。

回答by prettyvoid

Based on the accepted answer I wrote a simple Java method that builds the regex from an array of keywords

基于接受的答案,我编写了一个简单的 Java 方法,该方法从一组关键字构建正则表达式

public static String regexIfAllKeywordsExists(String[] keywords) {
    StringBuilder sb = new StringBuilder("^");

    for (String keyword : keywords) {
        sb.append("(?=.*\b");
        sb.append(keyword);
        sb.append("\b)");
    }

    sb.append(".+");

    return sb.toString();
}