如何使正则表达式只匹配每个匹配的第一次出现?

时间:2012-04-13 15:43:13

标签: javascript regex

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

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

首次出现“关键词”并首次出现“无论什么”,我可能会在那里放更多的词语。

4 个答案:

答案 0 :(得分:5)

从正则表达式中删除g标记:

/\b(keyword|whatever)\b/i

答案 1 :(得分: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
}

答案 2 :(得分:3)

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

答案 3 :(得分:1)

使用JavaScript正则表达式无法完成您所说的内容。有可能使用高级正则表达式功能,如.NET的无限制外观,但JavaScript的功能集非常有限。甚至在.NET中,为每个单词创建一个单独的正则表达式并逐个应用它们可能是最简单的;在JavaScript中,它是您唯一的选择。

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

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

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