5
/\b(keyword|whatever)\b/gi

如何修改上述 javascript 正则表达式以仅匹配每个单词的第一次出现(我相信这被称为非贪婪)?

“关键字”的第一次出现和“whatever”的第一次出现,我可能会在那里放更多的词。

4

4 回答 4

7

从您的正则表达式中删除g标志:

/\b(keyword|whatever)\b/i
于 2012-04-13T15:44:23.053 回答
4

你正在做的事情是用一个单一的正则表达式根本无法实现的。相反,您必须将您希望找到的每个单词存储在一个数组中,遍历它们以寻找答案,然后对于任何匹配项,将结果存储在一个数组中。

例子:

var words = ["keyword","whatever"];
var text = "Whatever, keywords are like so, whatever... Unrelated, I now know " +
           "what it's like to be a tweenage girl. Go Edward.";
var matches = []; // An empty array to store results in.
/* When you search the text you need to convert it to lower case to make it
   searchable.
 * We'll be using the built in method 'String.indexOf(needle)' to match 
   the strings as it avoids the need to escape the input for regular expression
   metacharacters. */

//Text converted to lower case to allow case insensitive searchable.
var lowerCaseText = text.toLowerCase();
for (var i=0;i<words.length;i++) { //Loop through the `words` array
    //indexOf returns -1 if no match is found
    if (lowerCaseText.indexOf(words[i]) != -1) 
        matches.push(words[i]);    //Add to the `matches` array
}
于 2012-04-13T15:44:28.157 回答
3

从您的正则表达式中删除 g 修饰符。然后它将只找到一个匹配项。

于 2012-04-13T15:44:16.160 回答
1

你所说的不能用 JavaScript 正则表达式来完成。使用高级正则表达式功能(如 .NET 的无限制后视)可能是可能的,但 JavaScript 的功能集非常有限。甚至在 .NET 中,为每个单词创建一个单独的正则表达式并一个一个地应用它们可能是最简单的;在 JavaScript 中,这是您唯一的选择。

贪婪仅适用于使用量词的正则表达式,例如/START.*END/. .意思是“任何字符”,意思*是“零个或多个”。定位后START.*贪婪地消耗文本的其余部分。然后它开始回溯,一次“回馈”一个字符,直到正则表达式的下一部分END成功匹配。
我们称这个正则表达式为“贪婪”,因为它匹配从 的第一次出现START到最后一次出现的所有内容END

如果可能有多个 "START"-to-"END" 序列,并且您只想匹配第一个,则可以将 a 附加?*以使其非贪婪:/START.*?END/。现在,每次.尝试使用下一个字符时,它首先检查它是否可以END在那个位置匹配。因此,它从第一个匹配START到之后的第一个END。如果你想单独匹配所有的“START”-to-“END”序列,你可以添加 'g' 修饰符/START.*?END/g

当然,这比这要复杂一些。例如,如果这些序列可以嵌套,如START…START…END…END? 如果我对这个答案有点得意忘形,那是因为理解贪婪是掌握正则表达式的第一个重要步骤。:-/

于 2012-04-13T17:40:19.563 回答