在下面的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);
});
答案 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