4

我正在尝试使用 JavaScript 和正则表达式突出显示一组关键字,我面临一个问题,我的关键字可能包含文字和特殊字符,如 @text #number 等。我正在使用单词边界来匹配和替换整个单词而不是部分词(包含在另一个词中)。

var pattern = new regex('\b '( + keyword +')\b',gi);

在这里,此表达式匹配整个关键字并突出显示它们,但是如果有任何关键字(如“数字:”)没有突出显示。

我知道\bword\b单词边界和特殊字符的匹配项是非字母数字字符,因此与上述表达式不匹配。你能告诉我我可以使用什么正则表达式来完成上述操作。

==更新==

对于上述内容,我尝试了 Tim Pietzcker 对以下正则表达式的建议,

expr: (?:^|\\b|\\s)(" + keyword + ")(?:$|\\b|\\s)

以上似乎可以让我使用字母数字和非字母数字字符匹配整个单词,但是只要关键字在关键字之前或之后有连续的 html 标记而没有空格,它就不会突出显示该关键字(例如社会保障* number: <br> *) 我尝试了以下正则表达式,但它替换了关键字前面的 html 标记

expr: (?:^|\b|\s|<[^>]+>)number:(?:$|\b|\s|<[^>]+>) 

这里是关键字编号:< br >(为 br 标签故意添加空格以避免浏览器解释标签)接下来没有空格,用关键字突出显示。

你能建议一个表达式,它会忽略整个单词的连续 html 标记,同时包含字母数字和非字母数字字符。

4

6 回答 6

2

2021 年更新:JS 现在支持lookbehind,所以这个答案有点过时了。

好的,所以你有两个问题: JavaScript 不支持后向查找,并且\b只能找到字母数字字符和非字母数字字符之间的边界。

第一个问题:关键字的词边界究竟是什么?我的猜测是它必须是\b边界或空白。如果是这种情况,您可以搜索

"(?:^|\\b|\\s)(" + keyword + ")(?:$|\\b|\\s)"

当然,关键字 like 周围的空白字符@number#也将成为匹配的一部分,但也许突出显示这些不是问题。在其他情况下,即如果存在可以匹配的实际单词边界,则空格不会成为匹配的一部分,因此在大多数情况下它应该可以正常工作。

您感兴趣的实际单词将在反向引用#1 中,因此如果您可以单独突出显示它,那就更好了。

编辑:如果在关键字之后/之前可能出现除空格之外的其他字符,那么我认为你唯一能做的(如果你坚持使用 JavaScript)是:

  1. 检查您的关键字是否以 alnum 字符开头。
  2. 如果是这样,\b请添加到您的正则表达式中。
  3. 检查您的关键字是否以 alnum 字符结尾。
  4. 如果是这样,请附加\b到您的正则表达式。

因此,对于keyword,使用\bkeyword\b; 为number:,使用\bnumber:;为@twitter,使用@twitter\b

于 2010-11-18T12:00:14.090 回答
1

我们需要寻找一个两边都有空白字符的子字符串。如果 JavaScript 支持后视,则如下所示:

var re = new RegExp('(?<!\\S)' + keyword + '(?!\\S)', 'gi');

虽然那行不通(但在 Perl 和其他脚本语言中)。相反,我们需要包含前导空白字符(或字符串的开头)作为匹配的开始部分(并且可以选择将我们真正要查找的内容捕获到 $1 中):

var re = new RegExp('(?:^|\\s)(' + keyword + ')(?!\\S)', 'gi');

只需考虑任何匹配开始的真实位置将是由返回的属性返回的字符之后的一个字符,并且如果您正在访问匹配的字符串,您需要删除第一个字符或简单地访问捕获的内容。.indexre.exec(string).slice(1)

于 2010-11-18T11:58:40.577 回答
0

也许你想做的是

'\b\W*(' + keyword + ')\W*\b'
于 2010-11-18T11:33:58.493 回答
0

向前看和向后看是您的答案:"(?=<[\s^])" + keyword + "(?=[\s$])". 括号中的位不包含在匹配项中,因此请包含其中关键字中不允许的任何字符。

于 2010-11-18T11:35:04.693 回答
0

试试这个应该可以的...

var pattern = new regex(@"\b"+Regex.escape(keyword)+@"\b",gi);
于 2011-09-09T20:31:46.427 回答
0

正如蒂姆正确指出的那样,\b这些棘手的事情与人们通常认为的工作方式不同。阅读此答案以了解有关此问题的更多详细信息以及您可以采取的措施。

简而言之,这是左侧的边界:

(?(?=\w)(?<!\w)|(?<!\W))

这是右边的边界:

(?(?<=\w)(?!\w)|(?!\W))

人们总是认为存在空间,但实际上没有。但是,既然您知道了真正的定义,就很容易将其构建到它们中。可以在上述两种模式中交换 和\w交换。或者可以将空格意识添加到 else 块中。\W\s\S

于 2010-11-18T13:58:15.480 回答