38

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

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

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

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

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

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

4

4 回答 4

65

你可以实现这将前瞻断言

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

在 Regexr 上查看

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

但它也适用于“晚餐肉 Foobar 意大利面”

于 2012-12-17T09:51:38.363 回答
5

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

\b(meat|pasta|dinner)\b

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

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

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

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

于 2012-12-17T09:11:19.987 回答
2

根据接受的答案,我编写了一个简单的 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();
}
于 2016-05-31T07:34:38.867 回答
2

stema 的答案在技术上是正确的,但它根本没有考虑性能。前瞻非常慢(在正则表达式的上下文中,它快如闪电)。即使使用当前的逻辑,正则表达式也不是最优的。

所以这里有一些测量值,是在包含所有三个单词的较大字符串上计算的,运行搜索 1000 次并使用四种不同的方法:

stema 的正则表达式

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

结果:605ms

优化的正则表达式

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

使用惰性匹配并且不需要 end all 选择器

结果:291ms

置换正则表达式

/(\bmeat\b.*?(\bpasta\b.*?\bdinner\b|\bdinner\b.*?\bpasta\b)|\bpasta\b.*?(\bmeat\b.*?\bdinner\b|\bdinner\b.*?\bmeat\b)|\bdinner\b.*?(\bpasta\b.*?\bmeat\b|\bmeat\b.*?\bpasta\b))/

结果:56ms

这很快,因为第一个模式正在匹配,如果最后一个模式匹配,它会比前瞻模式(300 毫秒)更慢

正则表达式数组

var regs=[/\bmeat\b/,/\bpasta\b/,/\bdinner\b/];
var result = regs.every(reg=>reg.test(text));

结果:26ms

请注意,如果字符串被设计为不匹配,则结果为:

  • 521毫秒
  • 220毫秒
  • 161ms - 慢得多,因为它必须经过所有分支
  • 14毫秒

如您所见,在所有情况下,仅使用循环都会快一个数量级,更不用说更容易阅读了。

最初的问题是要求一个正则表达式,所以我的答案是排列正则表达式,但我不会使用它,因为它的大小会随着搜索词的数量呈指数增长。

此外,在大多数情况下,这个性能问题是学术性的,但有必要强调一下。

于 2021-12-26T05:36:47.820 回答