查找文本中的确切单词,不包括引号单词

时间:2018-11-28 03:22:04

标签: javascript regex

在下面的javascript代码中,我需要在文本中找到确切的单词,但排除在引号之间的单词。这是我的尝试,正则表达式有什么问题?它应该找到除word22"word3"以外的所有单词。如果我在正则表达式中仅使用\b,则会选择准确的单词,但不会排除引号之间的单词。

var text = 'word1, word2, word22, "word3" and word4';
var words = [ 'word1', 'word2', 'word3' , 'word4' ];
words.forEach(function(word){
    var re = new RegExp('\\b^"' + word + '^"\\b', 'i');
    var  pos = text.search(re); 
    if (pos > -1)
        alert(word + " found in position " + pos);
});

2 个答案:

答案 0 :(得分:2)

首先,我们将使用一个函数来转义单词的字符,以防万一其中某些对正则表达式具有特殊含义。

_schemas

然后,我们构造一个正则表达式作为各个单词正则表达式之间的交替。对于每个单词,我们断言它以单词边界开头,以单词边界结尾,并且在其结尾和字符串结尾之间具有偶数个引号字符。 (请注意,从// from https://stackoverflow.com/a/30851002/240443 function regExpEscape(literal_string) { return literal_string.replace(/[-[\]{}()*+!<=:?.\/\\^$|#\s,]/g, '\\$&'); } 的末尾到字符串末尾只有一个引号,这很奇怪。)

word3

编辑:实际上,如果考虑周围情况,我们可以加快正则表达式的速度:

let text = 'word1, word2, word22, "word3" and word4';
let words = [ 'word1', 'word2', 'word3' , 'word4' ];
let regexp = new RegExp(words.map(word =>
'\\b' + regExpEscape(word) + '\\b(?=(?:[^"]*"[^"]*")*[^"]*$)').join('|'), 'g')

text.match(regexp)
// => word1, word2, word4

while ((m = regexp.exec(text))) {
  console.log(m[0], m.index);
}
// word1 0
// word2 7
// word4 34

答案 1 :(得分:1)

您将引号字符排除在外是错误的,实际上是匹配字符串后跟引号的开头。试试这个

var re = new RegExp('\\b[^"]' + word + '[^"]\\b', 'i');

此外,此网站非常有用,可以帮助您调试regex:https://regexpal.com

编辑:由于\b将在引号上匹配,因此需要进一步调整。不幸的是javascript不支持向后看,所以我们必须要有一点技巧。

var re = new RegExp('(?:^|[^"\\w])' + word + '(?:$|[^"\\w])','i')

这就是说

(?:         Don't capture this group
^ | [^"\w]) either match the start of the line, or any non word (alphanumeric and underscore) character that isn't a quote
word        capture and match your word here
(?:         Don't capture this group either
$|[^"\w)    either match the end of the line, or any non word character that isn't a quote again